Line protocol
Request :
[id:]<81digits>\r\n
Response:
[id:]<81digits>\r\n
[id:]NoSolution\r\n
Library or service?
- Cross process boundary, some overhead of course
- Cross Language
- Independent development
CPU-bounded stateless service
无状态的CPU密集型的服务
Probably the easiest type for load balancing and provisioning(需要多少资源)
- CPU is the dominant resource, how many cores needed to serve the traffic
Concurrent Models(并发模型)
- 5 Single event loop (并发但没有并行)
- 8 Single event loop with thread pool for computing
- 9 Multiple event loops
- 11 Multiple event loops with thread pool for computing
- 8/9/11 utilize multiple cores, 8/11 even for single client conn
- Different behavior when overloaded(过载时的表现不同)
- Memory Usage shots up (内存使用暴涨)
- How to monitor and protect
Load testing (负载测试)
- Local test (不通过网络)
- Batch client (通过网络,发给服务器,可以与第一种对比)
- Load test for maximum capacity (流水线,测试最大容量)
- Number of connection(并发连接数)
- Number of in-fly request a.k.a pipelines
- Stress testing(压力测试)
- Free running
- Performance testing(性能测试)
- 延迟
使用fastcgi + nginx做负载均衡
延迟的计算
使用两个环形缓冲区,记录一段时间内的请求数和总延迟,然后就可以计算平均延迟。
注意计算延迟时,以哪里为开始,如果选择不同的起始点,可能计算出来的平均延迟不一样。
禁用Nagle算法
过载保护
当client发送大量的request而且不接收response会发生什么?
对于使用线程池的server(非阻塞IO),处理request是异步的(asynchronous),IO线程读取request的速度比工作线程处理速度快,导致request堆积。导致内存使用量升高。
此外,server的发送缓冲区会不断堆积数据。
对于thread-per-connection模型的server,收发是同步的(阻塞IO),不会出现上面的问题。
可以对线程池的队列大小进行检查,如果太大,就返回错误并丢弃数据。这就解决了线程池队列过载的问题。
可以设置发送缓冲区的高水位回调,HighWaterMarkCallback。
G:为初始状态。当发送缓冲区达到5MB时,进入状态T(节流),如果发送缓冲区降低到0MB,也就是说客户端接收完了,重新回到状态G; 如果继续增加到10MB,就进入状态C,即断开连接。
负载均衡
Connection level: 连接级别的负载均衡。
Request level:请求级别的负载均衡。
负载 均衡策略:random(随机,要注意随机数发生器),round robin(简单,缺点:如果某个连接很busy,而某些连接很空闲,那么实际上不能很好的起到负载均衡的效果); 其他高级策略。
通过FastCGI作为初级的负载均衡。这样可以把一些工作责任交给成熟的web服务器,如nginx。nginx后面做负载均衡,这样服务器处理的连接都来自内网。nginx对后端的fastcgi是长连接的,它会复用这些连接。
进一步适应生产环境
- Heartbeat 心跳 (sudoku server向客户端发送心跳)
- Fault tolerance and failover (容错和故障转移)
- upgrading(升级)
通过server的web界面,停止某个server的心跳,客户端发现此server没有心跳了,就不会发送新的请求到此server,然后再通过此server的stat,当处理完后,即断开连接,而muduo 的client会reconnect。这样就实现了服务的重启。
Monitoring 监控/报警
- Periodically grab: 9982/sudoku/stats and graph with rrdtool
Provisioning
- Decide How much resource needed and how to deploy the service (流量有多大,单个cpu的计算能力,计算出需要多少个cpu)