老婆一起来上海工作,每个月消费立马上来了,做了一个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的更多相关文章

  1. 基于Nginx dyups模块的站点动态上下线并实现简单服务治理

    简介 今天主要讨论一下,对于分布式服务,站点如何平滑的上下线问题. 分布式服务 在分布式服务下,我们会用nginx做负载均衡, 业务站点访问某服务站点的时候, 统一走nginx, 然后nginx根据一 ...

  2. 基于nginx+xxl-job+springboot高可用分布式任务调度系统

    技术.原理讲解: <分布式任务调度平台XXL-JOB--源码解析一:项目介绍> <分布式任务调度平台XXL-JOB--源码解析二:基于docker搭建admin调度中心和execut ...

  3. Google 新实现的Protobuf RPC: grpc

    转自: http://www.dongliu.net/post/622450 Google 刚刚开源了grpc,  一个基于HTTP2 和 Protobuf 的RPC 实现. Protobuf 本身虽 ...

  4. 基于nginx tomcat redis分布式web应用的session共享配置

    一.前言 nginx 作为目前最流行的开源反向代理HTTP Server,用于实现资源缓存.web server负载均衡等功能,由于其轻量级.高性能.高可靠等特点在互联网项目中有着非常普遍的应用,相关 ...

  5. 基于nginx的tomcat负载均衡和集群

    要集群tomcat主要是解决SESSION共享的问题,因此我利用memcached来保存session,多台TOMCAT服务器即可共享SESSION了. 你可以自己写tomcat的扩展来保存SESSI ...

  6. 转: 基于nginx的hls直播系统

    转自:http://blog.csdn.net/cjsafty/article/details/9108587 看点: 1. 详细解解答了 nginx rtmp配置过程. 前写了一篇基于nginx的h ...

  7. Windows 环境下基于 nginx 的本地 PyPI 源

    Windows 环境下基于 nginx 的本地 PyPI 源的搭建: 1.登录 nginx 官网,下载安装包

  8. 基于nginx+lua+redis高性能api应用实践

    基于nginx+lua+redis高性能api应用实践 前言 比较传统的服务端程序(PHP.FAST CGI等),大多都是通过每产生一个请求,都会有一个进程与之相对应,请求处理完毕后相关进程自动释放. ...

  9. Ubuntu 14.10下基于Nginx搭建mp4/flv流媒体服务器(可随意拖动)并支持RTMP/HLS协议(含转码工具)

    Ubuntu 14.10下基于Nginx搭建mp4/flv流媒体服务器(可随意拖动)并支持RTMP/HLS协议(含转码工具) 最近因为项目关系,收朋友之托,想制作秀场网站,但是因为之前一直没有涉及到这 ...

随机推荐

  1. bash101总结

    看了 bash101 ,做的一些总结吧,都是些常见用法,易错 1. 有空格会显示多行 2.contine 书里太细了,有空补起来

  2. 程序设计实习MOOC / 程序设计与算法(三)第一周测验

    作业题: 7. 填空(2分)简单的swap 通过码是 ( 请参考公告中的“关于编程作业的说明”完成编程作业(请注意,编程题都要求提交通过码,在openjudge上提交了程序并且通过以后,就可以下载到通 ...

  3. Linux学习笔记——基于鸟哥的Linux私房菜

    Linux学习笔记--基于鸟哥的Linux私房菜 ***** ARM与嵌入式linux的入门建议 (1) 学习基本的裸机编程:ARM7或ARM9,理解硬件架构和控制原理 (这一步是绝对的根基) (2) ...

  4. 自建YUM源以及相关维护

    yum相关概念我这里就不做详细的讲解了,就是一个软件包管理工具.在企业中,很多时候进行编译了自己的RPM包,在搭建YUM的时候,希望将自定义的RPM加入到YUM源中,从而出现了下列方法. 一.配置私有 ...

  5. Ionic Js七:手势事件

    1.on-hold 长按的时间是500毫秒. HTML 代码 <button on-hold="onHold()" class="button">长 ...

  6. lnmp 一键安装包

    系统需求: CentOS/RHEL/Fedora/Debian/Ubuntu/Raspbian Linux系统 需要5GB以上硬盘剩余空间 需要128MB以上内存(如果为128MB的小内存VPS,Xe ...

  7. chromedriver与chrome版本对应表,firefox、geckodriver

     一. chromedriver与chrome对应表(记得就会更新): chromedriver版本 支持的Chrome版本 v2.36 v64-66 v2.35 v62-64 v2.34 v61-6 ...

  8. dSploitzANTI渗透教程之修改MAC地址与Wifi监听器

    dSploitzANTI渗透教程之修改MAC地址与Wifi监听器 dSploitzANTI基本配置 渗透测试是一种安全性较大的工作.所以,在实施渗透测试之前进行一些简单设置.如修改MAC地址.了解网络 ...

  9. 验证码60s倒计时前端效果

    <!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  10. MyBatis 插入时返回刚插入记录的主键值

    MyBatis 插入时返回刚插入记录的主键值 一.要求: 1.数据库表中的主键是自增长的,如:id: 2.获取刚刚插入的记录的id值: 二.源代码: 1.User.java package cn.co ...