Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

wfxiang08/rpc_proxy

Folders and files

NameName
Last commit message
Last commit date

Latest commit

History

30 Commits

Repository files navigation

RPC Proxy

开发环境

  • 工作目录: 约定使用 ~/goprojects/
    • mkdir -p rpc_proxy/src/git.chunyu.me/infra/
    • cd rpc_proxy/src/git.chunyu.me/infra/
    • git clone git@git.chunyu.me:infra/rpc_proxy.git
  • IDE(Pycharm + Go plugin)

基于Thrift的RPC Proxy

相关的子项目:

RPC的分层

Rpc Proxy分为4层,从前端往后端依次标记为L1, L2, L3, L4

L1层(应用层)

  • 最前端的RPC Client, 主要由thrift中间语言生成代码
  • 上面思路: 我们修改了transport&protocol两个模块,通过简单的修改得到了python版本的zerothrift
    • Java, Go等也能很方面地实现自己的RPC Client
    • 其他语言只要支持Thrift和ZeroMq, 都可以方便地实现自己的Client
# Transport层是所有的RPC服务都共用的(除非在同一个请求内部实现了并发)
_ = get_base_protocol(settings.RPC_LOCAL_PROXY)
protocol = get_service_protocol("typo")
from cy_typo.services.TypoService import Client
_typo_client = Client(protocol)
# 函数调用
rpc_result = _typo_client.correct_typo(content)
content = rpc_result.fixed
# 或者使用Pool
pool = ConnectionPool(10, "127.0.0.1:5550")
with pool.base_protocol() as base_protocol:
 protocol = get_service_protocol("typo", base_protocol)
 client = Client(protocol)

L2层(Proxy层)

  • 由于Python的进程功能太弱,不变在内部实现连接池等;如果让它们直接直连后端的Server, 则整个逻辑(connections)会非常乱,端口管理也会非常麻烦
  • 服务的发现和负载均衡放在Client端赖做也会极大地增加了Client端的开发难度和负担
  • Local Proxy层以产品为单位,负责发现所有的服务,并和L1层交互,让L1层不用关心服务部署的路径
  • Proxy层也有简单的负载均衡的处理
# Go中的deamon似乎不太容易实现,借助: nohup &可以实现类似的效果(Codis也如此)
# 默认的proxy(绑定: 127.0.0.0:5550)
nohup rpc_proxy -c config.ini -L proxy.log >/dev/null 2>&1 &
# 在测试服务器上部署,给大家开发测试使用的proxy
nohup rpc_proxy -c config_test.ini -L proxy_test.log >/dev/null 2>&1 &

L3层(负载均衡)

  • Java/Go等天然支持多线程等,基本上不需要负载均衡, 因此这一层主要面向python
  • 负责管理后端的Server, 自动进行负载均衡,以及处理后端服务的关闭,重启等异常情况
  • 负责服务的注册
  • 如果服务的正常关闭,会提前通知L2层,让L2层控制流量不再进入L3层的当前节点
  • 如果服务异常关闭,则5s左右, L2层就会感知,并且下线对应的节点
## 配置文件
config.ini
zk=rd1:2181,rd2:2181,mysql2:2181
# 线上的product一律以: online开头
# 而测试的product禁止使用 online的服务
product=test
verbose=0
zk_session_timeout=30
## Load Balance
service=typo
front_host=
front_port=5555
back_address=127.0.0.1:5556
# 使用网络的IP, 如果没有指定front_host, 则使用使用当前机器的内网的Ip来注册
ip_prefix=10.
## Server
worker_pool_size=2
## Client/Proxy
proxy_address=127.0.0.1:5550
# Go中的deamon似乎不太容易实现,借助: nohup &可以实现类似的效果(Codis也如此)
nohup rpc_lb -c config.ini -L lb.log >/dev/null 2>&1 &

L3层也可以直接就是Rpc服务层,例如:

  • 对于go, java直接在这一层提供服务
func main() {
	proxy.RpcMain(BINARY_NAME, SERVICE_DESC,
		// 默认的ThriftServer的配置checker
		proxy.ConfigCheckThriftService,
		// 可以根据配置config来创建processor
		func(config *utils.Config) proxy.Server {
			// 可以根据配置config来创建processor
			alg.InitGeoFix(FILE_GPS_2_SOGOU)
			processor := gs.NewGeoLocationServiceProcessor(&alg.GeoLocationService{})
			return proxy.NewThriftRpcServer(config, processor)
		})
}

L4层

  • 对于Python, rpc_proxy python框架即可
    • 通过thrift idl生成接口, Processor等
    • 实现Processor的接口
    • 合理地配置参数
      • 例如: worker_pool_size:如果是Django DB App则worker_pool_size=1(不支持异步数据库,多并发没有意义,即便支持异步数据库,Django的数据库逻辑也不支持高并发); 但是如果不使用DB, 那么Django还是可以支持多并发的
      • 注意在iptables中开启相关的端口
    • thrift只支持utf8格式的字符串,因此在使用过程中注意
      • 字符串如果是unicode, 一方面len可能和utf8的 len不一样,另一方面,数据在序列化时可能报编码错误
class TypoProcessor(object):
 def correct_typo(self, query):
 # print "Query: ", query
 result = TypoResult()
 new_query, mappings = typo_manager.correct_typo(query)
 result.fixed = new_query
 result.fixes = []
 for old, new in mappings:
 result.fixes.append(FixedTerm(old, new))
 return result
config_path = "config.ini"
config = parse_config(config_path)
endpoint = config["back_address"]
service = config["service"]
worker_pool_size = int(config["worker_pool_size"])
processor = Processor(TypoProcessor())
s = RpcWorker(processor, endpoint, pool_size=worker_pool_size, service=service)
s.connect(endpoint)
s.run()

系统架构

architecture

运维部署

  • 编译:
    • cd ~/goprojects/rpc_proxy/src/git.chunyu.me/infra/rpc_proxy
    • 运行编译脚本:
      • bash scripts/build_lb.sh
        • go build cmds/rpc_lb.go
        • 编译脚本和直接编译相比,将当前代码的版本,编译时间等打包到最终的文件中
      • bash scripts/build_proxy.sh
  • 运维
  • scp rpc_* node:/usr/local/rpc_proxy/bin/
    • sudo cp rpc_* /usr/local/rpc_proxy/bin/
    • 然后control_proxy.sh脚本和control_lb.sh脚本也需要部署在合适的地方
    • 注意 scripts目录下的脚本

About

基于thrift的服务注册和发现框架

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

AltStyle によって変換されたページ (->オリジナル) /