proxy.go 源码阅读
package main
import (
"net"
"time"
)
func initProxy() {
pLog.Infof("Proxying %s -> %s\n", pConfig.Bind, pConfig.Backend) //输出服务地址 后端服务地址列表
server, err := net.Listen("tcp", pConfig.Bind) //建立tcp连接
if err != nil {
pLog.Fatal(err)
}
waitQueue := make(chan net.Conn, pConfig.WaitQueueLen) //建立连接队列 队列默认等待队列长度---channel net.Conn ==控制最大排队队列
availPools := make(chan bool, pConfig.MaxConn) //建立最大连接数--channel bool=== 控制最大连接数
for i := 0; i < pConfig.MaxConn; i++ { //
availPools <- true
}
go loop(waitQueue, availPools)
for {
connection, err := server.Accept() //等待获取下一次连接
if err != nil {
pLog.Error(err)
} else {
pLog.Infof("Received connection from %s.\n", connection.RemoteAddr())
waitQueue <- connection
}
}
}
func loop(waitQueue chan net.Conn, availPools chan bool) {
for connection := range waitQueue { //循环等待队列中 排队等待需要处理的数据--连接
<-availPools //从通道中 连接池中取出一个
go func(connection net.Conn) {
handleConnection(connection)
availPools <- true //使用结束放回连接池中 目的控制连接数量 通道阻塞特性
pLog.Infof("Closed connection from %s.\n", connection.RemoteAddr())
}(connection)
}
}
func handleConnection(connection net.Conn) {
defer connection.Close()
bksvr, ok := getBackendSvr(connection)
if !ok {
return
}
remote, err := net.Dial("tcp", bksvr.svrStr)
if err != nil {
pLog.Error(err)
bksvr.failTimes++
return
}
//等待双向连接完成
complete := make(chan bool, 2)
oneSide := make(chan bool, 1)
otherSide := make(chan bool, 1)
go pass(connection, remote, complete, oneSide, otherSide)
go pass(remote, connection, complete, otherSide, oneSide)
<-complete
<-complete
remote.Close()
}
// copy Content two-way
func pass(from net.Conn, to net.Conn, complete chan bool, oneSide chan bool, otherSide chan bool) {
var err error
var read int
bytes := make([]byte, 256)
for {
select {
case <-otherSide:
complete <- true
return
default:
from.SetReadDeadline(time.Now().Add(time.Duration(pConfig.Timeout) * time.Second))
read, err = from.Read(bytes)
if err != nil {
complete <- true
oneSide <- true
return
}
to.SetWriteDeadline(time.Now().Add(time.Duration(pConfig.Timeout) * time.Second))
_, err = to.Write(bytes[:read])
if err != nil {
complete <- true
oneSide <- true
return
}
}
}
}
proxy.go 源码阅读的更多相关文章
- CI框架源码阅读笔记3 全局函数Common.php
从本篇开始,将深入CI框架的内部,一步步去探索这个框架的实现.结构和设计. Common.php文件定义了一系列的全局函数(一般来说,全局函数具有最高的加载优先权,因此大多数的框架中BootStrap ...
- Bean实例化(Spring源码阅读)-我们到底能走多远系列(33)
我们到底能走多远系列(33) 扯淡: 各位: 命运就算颠沛流离 命运就算曲折离奇 命运就算恐吓着你做人没趣味 别流泪 心酸 更不应舍弃 ... 主题: Spring源码阅读还在继 ...
- 【 js 基础 】【 源码学习 】backbone 源码阅读(一)
最近看完了 backbone.js 的源码,这里对于源码的细节就不再赘述了,大家可以 star 我的源码阅读项目(https://github.com/JiayiLi/source-code-stud ...
- 【JDK1.8】JDK1.8集合源码阅读——IdentityHashMap
一.前言 今天我们来看一下本次集合源码阅读里的最后一个Map--IdentityHashMap.这个Map之所以放在最后是因为它用到的情况最少,也相较于其他的map来说比较特殊.就笔者来说,到目前为止 ...
- Spring源码阅读笔记
前言 作为一个Java开发者,工作了几年后,越发觉力有点不从心了,技术的世界实在是太过于辽阔了,接触的东西越多,越感到前所未有的恐慌. 每天捣鼓这个捣鼓那个,结果回过头来,才发现这个也不通,那个也不精 ...
- Rpc框架dubbo-client(v2.6.3) 源码阅读(二)
接上一篇 dubbo-server 之后,再来看一下 dubbo-client 是如何工作的. dubbo提供者服务示例, 其结构是这样的!dubbo://192.168.11.6:20880/com ...
- 【Dubbo源码阅读系列】之远程服务调用(上)
今天打算来讲一讲 Dubbo 服务远程调用.笔者在开始看 Dubbo 远程服务相关源码的时候,看的有点迷糊.后来慢慢明白 Dubbo 远程服务的调用的本质就是动态代理模式的一种实现.本地消费者无须知道 ...
- 【Dubbo源码阅读系列】服务暴露之远程暴露
引言 什么叫 远程暴露 ?试着想象着这么一种场景:假设我们新增了一台服务器 A,专门用于发送短信提示给指定用户.那么问题来了,我们的 Message 服务上线之后,应该如何告知调用方服务器,服务器 A ...
- 【Dubbo源码阅读系列】服务暴露之本地暴露
在上一篇文章中我们介绍 Dubbo 自定义标签解析相关内容,其中我们自定义的 XML 标签 <dubbo:service /> 会被解析为 ServiceBean 对象(传送门:Dubbo ...
随机推荐
- mac os X中关于dayone缓存的实际文件位置
最近刚安装了mac版的dayone软件,感觉蛮不错的!以前一直用iphone版的,mac版是要米的,68米丫!想了想还是一咬牙:买了! 我用的是iCloud同步,虽然资料放在云中,但本地还是会有缓存的 ...
- 开发composer包,打通github和packagist,并自动更新
1. 首先需要本地安装好composer,并配置好环境变量,在命令行输入composer,显示以下信息就表示正常安装 2. 在github对应项目的根目录下进行初始化composer 初始化完成后,就 ...
- rotate image(旋转数组)
You are given an n x n 2D matrix representing an image. Rotate the image by 90 degrees (clockwise). ...
- SQL的几种连接:内连接、左联接、右连接、全连接、交叉连接
SQL连接可以分为内连接.外连接.交叉连接. 数据库数据: book表 stu表 1.内连接 ...
- 网站SEO优化问答精选
1.百度每更新一次,网站的收录就减少很多,但是我每天都增加伪原创的内容啊? 这个问题大多数是因为网站权重导致百度不够重视你:另外就是文章质量度不高,没有可读性或是原创度太低,尽管百度会收录,但是经过一 ...
- C++string函数之strcat_s
跟上一篇的strcpy_s一样,是新推出的较为安全的strcat函数 strcat_s脱胎于strcat,用于两个字符串的链接,strcat(str1,str2)直接返回新的str1. 但在vs200 ...
- Linux服务器安全审计工具与流程完全指南
http://Linux.chinaitlab.com/server/860516.html 当今许多linux服务器都不是刚刚部署完毕的新机器,有专业的Linux系统管理员进行定期维护,IT技术人员 ...
- 代码审计之SQL注入:BlueCMSv1.6 sp1
Preface 这是一篇纪录关于BlueCMSv1.6 sp1两个SQL注入的审计过程,原文来自代码审计之SQL注入:BlueCMSv1.6 sp1 ,主要纪录一下个人在参考博文复现这两个漏洞经过. ...
- linux配置https站点
配置https站点呢,那就需要https证书,证书从何而来,花钱买?no,no,no,阿里有免费的,只是比较难发现,下面就图文解说一下怎么买免费的阿里https证书 首先阿里云,登录,购买链接———— ...
- centOS7固定IP
接续安装完成centOS虚拟机后,重启完成后,会出现如下的界面: 这里,我们使用root帐号和已配置的root密码进行登陆,登陆完成后,输入如下命令,运行结果如下图: dhclient 通过上述命令, ...