分享
  1. 首页
  2. 文章

Golang TcpProxy和Nodejs TcpProxy

gofounder · · 1224 次点击 · · 开始浏览
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

自己平时的工作基本都在php和nodejs之间徘徊,但是目前面对python和java的猛烈攻击呢,其实内心有一种隐隐的痛"PHP是世界上最好的语言","nodejs在cpu密集时服务彻底瘫痪"。。。

看了半个月python真实发现,其实它太像php语言了,所以基本不用怎么理解就会了。golang看了1个多月了真的得多写多看源代码才能收获,别看才30几个关键字但是内容真的很多,golang的性能是真的高可以大大缩减服务器开销,举个例子web服务中php需要100台机器,那么golang可能只需要10台甚至更少!

最近在研究mysql proxy,其实mysql本身是支持代理的,但是想自己尝试下这样就会很灵活:

  • 灵活slb mysql负载均衡
  • 读写直接通过proxy直接进行判断
  • 提前预警或拒绝危险性sql
  • ...太多太多太多好处

以下是golang mysql proxy的代码

package main
 
import (
 "net"
 "fmt"
 "time"
)
 
const (
 MYSQL_ADDRESS = "mysq-host"
 MYSQL_PORT = "3306"
)
 
func main() {
 listener, err := net.Listen("tcp", ":1234")
 if err != nil {
 fmt.Println("tcp", err.Error())
 return
 } else {
 fmt.Println("tcp", listener.Addr(), "success")
 }
 
 for {
 user, err := listener.Accept()
 if err != nil {
 fmt.Println("accept error: ", err.Error())
 continue
 }
 go proxyRequest(user)
 }
}
 
 
//打理用户请求
func proxyRequest(user net.Conn) {
 
 fmt.Println(user.LocalAddr())
 bytes := make([]byte, 10240)
 
 conn, err := net.Dial("tcp", MYSQL_ADDRESS + ":" + MYSQL_PORT)
 
 if err != nil {
 fmt.Println(conn.RemoteAddr(), "error:", err.Error())
 conn.Close()
 return
 }
 
 ch := make(chan bool, 1)
 go proxyResponse(user, conn, ch)
 
 for {
 n, err := user.Read(bytes)
 if err != nil {
 break
 }
 fmt.Println(string(bytes[:n]))
 conn.Write(bytes[:n])
 }
 
 defer close(ch)
 
 select {
 case <-ch:
 conn.Close()
 user.Close()
 fmt.Println("proxy over")
 case <-time.After(time.Second * 60):
 fmt.Println("proxy timeout")
 }
 
}
 
//代理服务的返回给用户
func proxyResponse(user net.Conn, service net.Conn, ch chan bool) {
 bytes := make([]byte, 10240)
 
 for {
 n, err := service.Read(bytes)
 if err != nil {
 break
 }
 user.Write(bytes[:n])
 }
 
 ch <- true
}

以下是nodejs简单的proxy

var net = require('net');
var model = require('../../models/proxy');
var trace = require('../../libs/trace');
//代理表
var proxys = [];
//tcp server
var server = null;
//proxy information
var information = {count: 0, success: 0, error: 0};
/**
 * 启动服务
 * @param info array
 * @param callback function
 */
exports.start = (info, callback) => {
 model.getProxyListFromServer(info.id, (err, result)=> {
 if (err) {
 callback(err, err);
 } else {
 proxys = result;
 initServer(info.port, info.to_host, info.to_port);
 callback(null);
 }
 });
};
/**
 * 停止服务.
 * @return bool
 */
exports.stop = function () {
 if (server && server.listening) {
 server.close();
 server = null;
 return true;
 }
 return false;
};
/**
 * 获取信息
 * @return object
 */
exports.getInfo = () => {
 return information;
};
/**
 * 初始化tcp proxy server.
 * @param port
 * @param toHost
 * @param toPort
 */
function initServer(port, toHost, toPort) {
 server = net.createServer((client)=> {
 information.count++;
 client.on('end', () => {
 connect.end();
 });
 var connect = net.createConnection({host: toHost, port: toPort}, (err)=> {
 });
 connect.on('error', (err)=> {
 information.error++;
 });
 connect.on('end', ()=> {
 information.success++;
 });
 client.pipe(connect);
 connect.pipe(client);
 // client.on('data', function (data) {
 // var buf = Buffer.from(data);
 // console.log('data: ' + buf.toString());
 // });
 });
 server.listen(port, (err) => {
 if (err) {
 trace.log('proxy server error', err);
 process.exit();
 }
 trace.log('proxy server started', port);
 });
}

有疑问加站长微信联系(非本文作者)

本文来自:Segmentfault

感谢作者:gofounder

查看原文:Golang TcpProxy和Nodejs TcpProxy

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

关注微信
1224 次点击
暂无回复
添加一条新回复 (您需要 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传

用户登录

没有账号?注册
(追記) (追記ここまで)

今日阅读排行

    加载中
(追記) (追記ここまで)

一周阅读排行

    加载中

关注我

  • 扫码关注领全套学习资料 关注微信公众号
  • 加入 QQ 群:
    • 192706294(已满)
    • 731990104(已满)
    • 798786647(已满)
    • 729884609(已满)
    • 977810755(已满)
    • 815126783(已满)
    • 812540095(已满)
    • 1006366459(已满)
    • 692541889

  • 关注微信公众号
  • 加入微信群:liuxiaoyan-s,备注入群
  • 也欢迎加入知识星球 Go粉丝们(免费)

给该专栏投稿 写篇新文章

每篇文章有总共有 5 次投稿机会

收入到我管理的专栏 新建专栏