基于nginx实现protobuf RPC
老婆一起来上海工作,每个月消费立马上来了,做了一个android记账应用,把每笔帐都实时记录进去。开始是单机版的,只能两个人分别记,月底再merge一下。刚好有一台阿里云的ECS,于是准备升级为带服务端版的,通信协议可以直接用android的http库,但考虑到越来越多的app应用都开始走私有协议(比如原来运维的手机淘宝),定制一套个性化的协议本身就比较麻烦,扩展性也不好,于是想到了protobuf-rpc。但还需要一个成熟的network frame(手写的话不知道要搞到什么时候),于是想到了nginx。
github地址:https://github.com/zmkeil/nrpc
为什么选nginx
Nginx是一款高性能的web服务器,清晰的代码结构及优良的模块化,非常易于扩展为各种各样的网络服务器。其构建的基础组件如内存池,链表等及event,network接口全部包含在core/event目录中,而且性能非常高,直接面向互联网服务,网络IO方面没有任何问题。
怎么使用nginx
为了保证对nginx的修改最少,我将RPC框架当成nginx的一个模块,启动时将它动态加入到nginx的模块列表(ngx_modules[])中去。
另外提供非常简易的编程接口(和大部分RPC实现类似),监听端口、protobuf service等信息都可以在应用程序初始化阶段通过编程接口来设置,所有初始化完成之后,应用程序可以直接调用server.start()来启动服务,这个方法实际上是调用nginx的main函数(改名为ngx_start),然后就进入了nginx的正常流程,初始化所有模块(包括我们的NRPC模块),然后打开所有监听端口,并启动work进程,开始接受request。主进程自动进入deamon模式,并且设置相应的信号处理程序。所以应用程序在调用完server.start()后,就可以直接return了(实际上是不会执行到的)。
此外,nginx的core、event模块的配置,可以直接用nginx.conf文件来配置,就像原汁原味的nginx一样。
启动过程如下图所示:
右侧是简易的应用程序流程:
1、首先创建一个server,包括一些初始化工作
2、然后通过server.push_service_set()接口,为该server添加一个service_set,并配置其监听地址,一般为“0.0.0.0:port”。同时,会将该service_set信息添加到全局变量nrpc_listens[]中去。
3、然后向该service_set中添加service。这里对service使用了两层逻辑的管理:一个监听端口对应一个service_set,一个service_set可以包含多个service。因为主要是考虑面向公网应用,服务器资源宝贵,可以同时提供多种服务。
4、最后通过server.start()启动服务,如前所述,这回调用nginx的启动流程,打开所有监听端口。这里设置了nrpc的ls->handler = ngx_nrpc_init_connection,后续所有nrpc的请求入口就从这里开始。
特性
该模块实现了RPC的基本功能,比如端口配置,service添加/删除,超时设置,local_session_context等。另外还有一些常用的功能。
服务端:
1.继承了nginx的core、event模块的所有特性
2.连接保持及复用
3.QPS并发限流
服务端流程如下图:
大致流程如上图:
1、第一行3个函数和第三行1个函数,都是通过nginx的event、network接口接收/发送请求,nginx是完全非阻塞的事件模型,写起来和一般的同步写法有些区别
2、中间一行的函数则是实现了protobuf的框架接口。这里提供的多种protocol,主要是针对输入的,目前实现的只接受protobuf格式的请求,考虑到http的通用性,以后会实现接口http格式的请求,内部转化成protobuf格式,返回response时再转化成http格式。
客户端:
利用pthread实现,和服务端是隔离的,代码单独组织在channel.cpp、connection_pool.cpp和controller.cpp(和服务端共用的)中,一些特性如下:
1.提供同步、异步两种模式,用户可以串行发请求,并同步处理返回结果;也可以并发发请求,异步处理结果,并提供join功能
2.自动重试机制,但RPC失败时,客户端会自动重试多次(可配置),不需要用户代码做任何处理
3.实现一个简单的连接池,可以复用连接
客户端流程如下图:
结束语
github中的sample有示例代码,详细的使用方法README中有介绍,https://github.com/zmkeil/nrpc。
这算是我的第一个开源项目,代码有很多不严谨的地方,欢迎指正,欢迎使用。
另外特别以此纪念爷爷,爷爷去世有两周了,在这个临近新春的寒冷的四九天里,是遗憾吧,或是解脱吧。爷爷生于旧社会,经历过军阀、日本侵华、文革,一生勤勤恳恳,和气待人,村里造桥铺路,春耕秋收,都事事为先,受人尊敬。记得初中时,我有一次作文比赛得到一等奖,题目是第一次XX,我写的是第一次写毛笔字,爷爷为我调墨铺纸。
基于nginx实现protobuf RPC的更多相关文章
- 基于Nginx dyups模块的站点动态上下线并实现简单服务治理
简介 今天主要讨论一下,对于分布式服务,站点如何平滑的上下线问题. 分布式服务 在分布式服务下,我们会用nginx做负载均衡, 业务站点访问某服务站点的时候, 统一走nginx, 然后nginx根据一 ...
- 基于nginx+xxl-job+springboot高可用分布式任务调度系统
技术.原理讲解: <分布式任务调度平台XXL-JOB--源码解析一:项目介绍> <分布式任务调度平台XXL-JOB--源码解析二:基于docker搭建admin调度中心和execut ...
- Google 新实现的Protobuf RPC: grpc
转自: http://www.dongliu.net/post/622450 Google 刚刚开源了grpc, 一个基于HTTP2 和 Protobuf 的RPC 实现. Protobuf 本身虽 ...
- 基于nginx tomcat redis分布式web应用的session共享配置
一.前言 nginx 作为目前最流行的开源反向代理HTTP Server,用于实现资源缓存.web server负载均衡等功能,由于其轻量级.高性能.高可靠等特点在互联网项目中有着非常普遍的应用,相关 ...
- 基于nginx的tomcat负载均衡和集群
要集群tomcat主要是解决SESSION共享的问题,因此我利用memcached来保存session,多台TOMCAT服务器即可共享SESSION了. 你可以自己写tomcat的扩展来保存SESSI ...
- 转: 基于nginx的hls直播系统
转自:http://blog.csdn.net/cjsafty/article/details/9108587 看点: 1. 详细解解答了 nginx rtmp配置过程. 前写了一篇基于nginx的h ...
- Windows 环境下基于 nginx 的本地 PyPI 源
Windows 环境下基于 nginx 的本地 PyPI 源的搭建: 1.登录 nginx 官网,下载安装包
- 基于nginx+lua+redis高性能api应用实践
基于nginx+lua+redis高性能api应用实践 前言 比较传统的服务端程序(PHP.FAST CGI等),大多都是通过每产生一个请求,都会有一个进程与之相对应,请求处理完毕后相关进程自动释放. ...
- Ubuntu 14.10下基于Nginx搭建mp4/flv流媒体服务器(可随意拖动)并支持RTMP/HLS协议(含转码工具)
Ubuntu 14.10下基于Nginx搭建mp4/flv流媒体服务器(可随意拖动)并支持RTMP/HLS协议(含转码工具) 最近因为项目关系,收朋友之托,想制作秀场网站,但是因为之前一直没有涉及到这 ...
随机推荐
- jquery validate不用submit提交,用js提交的
jquery validate控件 默认是使用submit提交的, 要想改成使用button的click事件处理函数中手工提交, 可以按照如下方式操作: 1 绑定form的validate, 2 然后 ...
- tp5总结(四)
数据库 1.数据库配置 1-1.配置文件配置[http://ww:7070/tp5-3/public/] 1-2.Db::connect配置[数组和字符串方式][http://ww:7070/tp5- ...
- hdoj1171 Big Event in HDU(01背包 || 多重背包)
题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=1171 题意 老师有一个属性:价值(value).在学院里的老师共有n种价值,每一种价值value对应着 ...
- 喜大普奔!Django官方文档终于出中文版了
喜大普奔!Django官方文档终于出中文版了 文章来源:企鹅号 - Crossin的编程教室 昨天经 Sur 同学告知才发现,Django 官方文档居然支持中文了! 之所以让我觉得惊喜与意外,是因为: ...
- 推荐:这才是你寻寻觅觅想要的 Python 可视化神器
Plotly Express 是一个新的高级 Python 可视化库:它是 Plotly.py 的高级封装,它为复杂的图表提供了一个简单的语法. 受 Seaborn 和 ggplot2 的启发,它专门 ...
- 【Performance】chrome调试面板
本篇文章以chrome版本67.0.3396.99为例,说明性能方面的调试.
- python opencv3 矩形 圆形边框
git:https://github.com/linyi0604/Computer-Vision # coding:utf8 import cv2 import numpy as np # 读入图像 ...
- BeautifulSoup与Xpath解析库总结
一.BeautifulSoup解析库 1.快速开始 html_doc = """ <html><head><title>The Dor ...
- PHP中var_export和var_dump的区别
var_dump -- 此函数显示关于一个或多个表达式的结构信息,包括表达式的类型与值. var_export -- 输出或返回一个变量的字符串表示, 它和 var_dump() 类似,不同的是其返回 ...
- springboot中使用JOIN实现关联表查询
* 首先要确保你的表和想要关联的表有外键连接 repository中添加接口JpaSpecificationExecutor<?>,就可以使用springboot jpa 提供的API了. ...