基于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协议(含转码工具) 最近因为项目关系,收朋友之托,想制作秀场网站,但是因为之前一直没有涉及到这 ...
随机推荐
- Visual Studio 2017 发布 附带下载地址
链接: https://pan.baidu.com/s/1kFjGwyj5HwabvmJKiyLF_g 提取码: 关注公众号[GitHubCN]回复获取 winform框架源码-Devexpre ...
- USACO 完结的一些感想
其实日期没有那么近啦……只是我偶尔还点进去造成的,导致我没有每一章刷完的纪念日了 但是全刷完是今天啦 讲真,题很锻炼思维能力,USACO保持着一贯猎奇的题目描述,以及尽量不用高级算法就完成的题解……例 ...
- USACO 4.2 Job Processing
Job ProcessingIOI'96 A factory is running a production line that requires two operations to be perfo ...
- MVC、MVP和MVVM的异同
No1: Model一般用来保持程序的数据状态,比如数据存储.网络请求等 No2: Android开发中应用到MVC的地方:比如ListView与Adapter,如果把ListView看作View层, ...
- HDU - 1051 Wooden Sticks 贪心 动态规划
Wooden Sticks Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) ...
- Java 中线程安全问题
不好意思,一个国庆假期给我放的都不知道东西南北了,放松,很放松,差一点就弃更了,感谢那些催更的小伙伴们! 虽然没有更新,但是日常的学习还是有的,以后我尽量给大家分享一些通用知识,非技术. 但是本期还是 ...
- leetcode 入门第一题 4ms? 8ms? Two Sum
今天开启leetcode 入门第一题 题意很简单,就是一个数组中求取两数之和等于目标数的一对儿下标 1.暴力 n^2 两个for循环遍历 用时0.1s 开外 代码就不用写了 2.二分 nlogn 我们 ...
- 你见过这些JavaScript的陷阱吗?
一.成员操作符 Number.prototype.testFn=function () { console.log(this<0, this.valueOf()); } var num = -1 ...
- tomcat启动startup.bat一闪而过的问题处理方式
tomcat在启动时,会读取环境变量的信息,需要一个CATALINA_HOME 与JAVA_HOME的信息,CATALINA_HOME即tomcat的主目录,JAVA_HOME即Java安装的主目录, ...
- Struts2 (上)
Struts2简介 Struts2框架的作用 Struts2是一个基于MVC设计模式的Web应用框架 它本质上相当于一个servlet,在MVC设计模式中,Struts2作为控制器(Controlle ...