发表于: 2017-09-01 17:40:19

1 940


【今日完成】

在自己写的service里,引入Memcache缓存的代码。
写好相关逻辑,比如有了缓存就不从数据库里查了。

首先,要在Memcached里面添加内容,该内容必须可以序列化,所以一般我们都实现一个序列化接口。


在service层里面引入Memcached代码,如图:

如果Memcached里面没有,则从数据库中读,如果有,则在缓存里拿,不必进入数据库。

运行效果如下,只有第一次是去数据库中拿数据,以后每次都是通过缓存读数据

使用Jmeter做测试,当没有使用缓存时,每次都从数据库取,效果如下:


当使用缓存时,可以看见,时间大幅度缩短,证明缓存确实很有帮助。



===================================================================


学习了Nginx底层的实现:


Nginx是一个master主进程控制N个worker进程来工作的。一般Worker进程的数量与CPU核数相等。那么那么少的数量是如何实现高并发的呢?那是因为Nginx工作原理是异步式非堵塞。所谓异步式非堵塞,举个例子:首先,请求过来,要建立连接,然后再接收数据,接收数据后,再发送数据。具体到系统底层,就是读写事件,而当读写事件没有准备好时,必然不可操作,如果不用非阻塞的方式来调用,那就得阻塞调用了,事件没有准备好,那就只能等了,等事件准备好了,你再继续吧。阻塞调用会进入内核等待,cpu就会让出去给别人用了,对单线程的worker来说,显然不合适,当网络事件越多时,大家都在等待呢,cpu空闲下来没人用,cpu利用率自然上不去了,更别谈高并发了。好吧,你说加进程数,这跟apache的线程模型有什么区别,注意,别增加无谓的上下文切换。所以,在nginx里面,最忌讳阻塞的系统调用了。不要阻塞,那就非阻塞喽。非阻塞就是,事件没有准备好,马上返回EAGAIN,告诉你,事件还没准备好呢,你慌什么,过会再来吧。好吧,你过一会,再来检查一下事件,直到事件准备好了为止,在这期间,你就可以先去做其它事情,然后再来看看事件好了没。虽然不阻塞了,但你得不时地过来检查一下事件的状态,你可以做更多的事情了,但带来的开销也是不小的。所以,才会有了异步非阻塞的事件处理机制,具体到系统调用就是像select/poll/epoll/kqueue这样的系统调用。它们提供了一种机制,让你可以同时监控多个事件,调用他们是阻塞的,但可以设置超时时间,在超时时间之内,如果有事件准备好了,就返回。这种机制正好解决了我们上面的两个问题,拿epoll为例(在后面的例子中,我们多以epoll为例子,以代表这一类函数),当事件没准备好时,放到epoll里面,事件准备好了,我们就去读写,当读写返回EAGAIN时,我们将它再次加入到epoll里面。这样,只要有事件准备好了,我们就去处理它,只有当所有事件都没准备好时,才在epoll里面等着。这样,我们就可以并发处理大量的并发了,当然,这里的并发请求,是指未处理完的请求,线程只有一个,所以同时能处理的请求当然只有一个了,只是在请求间进行不断地切换而已,切换也是因为异步事件未准备好,而主动让出的。这里的切换是没有任何代价,你可以理解为循环处理多个准备好的事件,事实上就是这样的。与多线程相比,这种事件处理方式是有很大的优势的,不需要创建线程,每个请求占用的内存也很少,没有上下文切换,事件处理非常的轻量级。并发数再多也不会导致无谓的资源浪费(上下文切换)。更多的并发数,只是会占用更多的内存而已。 我之前有对连接数进行过测试,在24G内存的机器上,处理的并发请求数达到过200万。现在的网络服务器基本都采用这种方式,这也是nginx性能高效的主要原因。



http://tengine.taobao.org/book/chapter_02.html这篇博文介绍的比较详细,看完会对Nginx的理解上一个新的台阶


【明日计划】

看看Redis

【今日收获】

在service里面引入了Memcached,经过Jmeter测试,确实有很大改善

看了一下Nginx的原理,理解了为何它这么牛,可以处理这么多并发


【任务进度】

应该无延期风险

http://task.ptteng.com/zentao/project-burn-268.html


返回列表 返回列表
评论

    分享到