一个通用的互联网服务端程序长什么样?
1. 构建和优化的目标
- 可扩展性:用普通的服务器集群构建高性能服务集群
一般配置:12核,48GB,1TB(raid后),千兆网卡 - 高稳定性:核心服务要求4个9的稳定性(99.9999%)
- 架构的优雅性:要支持热启动上线,线上流量自由切换,方便的服务器扩容和替换,拆成多个独立的服务集群每个集群根据负载动态调整
- 算法的高效性:在架构合理的基础上追求算法上和编译级别的优化
- 合理的资源利用率:好的后端服务我认为应该是 每台机器负载均匀,不会出现单个因素的瓶颈。mem-usg:50%-70%,cpu-idl:50%且无显著尖峰, 网卡:打满最好,磁盘io:尽量少。
举个例子:
![内存](http://7u2g5z.com1.z0.glb.clouddn.com/屏幕快照 2015-01-08 上午10.50.52.png)
![cpu](http://7u2g5z.com1.z0.glb.clouddn.com/屏幕快照 2015-01-08 上午10.51.18.png)
![io](http://7u2g5z.com1.z0.glb.clouddn.com/屏幕快照 2015-01-08 上午10.52.00.png)
![io](http://7u2g5z.com1.z0.glb.clouddn.com/屏幕快照 2015-01-08 上午10.52.16.png)
![网卡](http://7u2g5z.com1.z0.glb.clouddn.com/屏幕快照 2015-01-08 上午10.52.34.png)
![网卡](http://7u2g5z.com1.z0.glb.clouddn.com/屏幕快照 2015-01-08 上午10.52.43.png)
2. 部署到线上的样子
![](http://7u2g5z.com1.z0.glb.clouddn.com/屏幕快照 2015-01-07 下午5.40.28.png)
bin/ : 可运行的binary
conf/:binary使用的配置信息
confSH/:shell使用的配置信息
data/:程序本地加载的数据文件
log/:日志文件目录
shell:bash shell,python 脚本文件夹
2. 应该有的功能
- supervise 启动,当程序出现意外崩溃时需要能够快速重启以能够减少pv lost
- 启动成功探测脚本 ,向端口发送伪造数据,探测是否启动成功
- 日志按照小时切分,并且准实时同步到hdfs供后续的分析统计使用(这是一个单独的topic,需要单独说明)
- 合理的日志内容用于快速问题定位:最佳日志实践by网易
- 授权机制:支持配置调用ip的白名单和黑名单。这样可以有效避免线下测试等无效流量对线上服务集群带来影响。
3. 更好的功能
- 自包含:仅需要同步文件夹即可发布到线上,类似的思想:docker
- 尽量较少的启动时间:一般由于较多的本地磁盘加载操作导致,负面作用是:令人发狂的上线和回滚时间。
- 作为被调用的服务端,需要有分布式的服务定位系统,这样可以支持:服务器迁移,扩容,流量迁移。使服务更加接近99.9999%的可靠性。
4. 服务内部的架构
-
类图
![一个常见的c++后端服务](http://7u2g5z.com1.z0.glb.clouddn.com/屏幕快照 2015-01-08 下午1.54.16.png) -
说明
CEpendingpool : 封装了epoll实现,内置可配置长度的队列,用户接收和缓存大量的client连接,如果逻辑很轻,单独压次模块可以到达W级别的qps。
CServer: 服务器的总控类,其中启动了N个work线程和1个update线程。work线程:从pool中fetch一个连接,反序列化消息,根据request_type来分发调用不同的处理逻辑。
CResourceManager:资源管理类,多线程服务模型如果每个线程分配资源会造成大量内存浪费。所以把可以共享的资源全局加载,多个线程可以访问到。另一个重要的功能是: 索引替换要支持双buffer切换即热换库。
CServerRouter:维护按照不同请求->服务的路由关系,这一层可以拆成单独的进程。
CAAAService: 实现了IService的接口,可单独拆开给不同rd参与实现,以实现业务的快速迭代。
CLogAgent: 实现根据日志的配置,打印日志的功能:按小时切分/滚动,一般分:AAA.log和AAA.log.wf。
CConfigReader:实现读取&重新加载配置文件的功能。 -
该方案的优点
- 框架搭建好之后可以根据不同的request_type快速切分任务并行开发,很好的支持快速迭代;
- 同步的多线程模型,性能很好。
-
该方案的缺点
- 出现过由于某个request_type对应的服务处理较慢,整个服务卡死的情况。
- 在实际开发中引入到线程中大量重复变量,导致内存使用率虚高。
- 不支持服务降级,每个request_type的服务优先级一致。
5. 更多
- 互联网服务一般需要多个不同的服务集群协调工作才能提供完整服务,这就需要后端server与server之间相互通信(详见下一篇简书)。
- 后端server之上一般还会有webserver和php层提供功能整合和模版渲染的功能。
网友评论