五一假期结束了,突然想到3周前去上班的路上看到槐花开的正好。放假也没能采些做槐花糕,到下周肯定就老了。一年就开一次的东西,比如牡丹,花期也就一周。而花开之时,玫瑰和月季无法与之相比。明日黄花蝶也愁。想起去年开车在美国最美的加州一号公路上,哼着美国乡村音乐,以最正确的方式打开着最美的风景,心里却为现在已经想不起来的一个什么理由不开心,好可惜。从来没把青春当做资本,却也不愿看看时光流走时自己的碌碌无为。
终于确定了今年要做的事情。然而就是这个也并不容易。年初签绩效的时候,老大问我一些想法,说我能力比较强,老是做项目对我的成长不好。我说没关系,成长这种事终究要靠自己的。我之所以这样说是因为自己也没想到解决办法。那么这时候说什么也只是给别人出难题而已。为难别人的事情是绝对不能做的。
第一次听到中间件这个名词是在人人的时候,那时候的中间件是基于ICE的,用C++写的。推荐几度人脉,新鲜事(feed流),antispam这些当时觉得最有技术含量的工作都包含在中间件里。但是这些东西都已经很成熟了,因为是C++写的,需要专人维护,但是维护的人平时又很闲,非常鸡肋。所以在C++的哥哥都离职之后,就用java改写了。改写之后用的是hessian协议了,就开始说RPC了,不讲ICE了。有些东西,错过了就是一辈子。因为当时是菜鸟一枚,所以到现在也没了解什么是ICE(下次同事聚会的时候可以唠一唠,mark一下)但是那时候还没有zookeeper(说的自己好像是考古文物~~),我们自己写了一个用于配置管理的,用socket作为广播站发送UDP报文给所有业务应用服务,用心跳监控数据库的健康状况给业务端发消息的。这种做法,估计也和ICE思想的移植有关。想起五四新文化运动时,胡适说:"我们这一代的白话,如同裹小了的脚放不好一样写不好白话。" 我从山中来,带着兰花草…… 额……又跑题了,拉回来。
今天的主题是IO。因为ES和Solr相比,最吸引人的一个优点是它使用了Netty框架。而Solr使用了jetty,当然用tomcat,resin这样的web容器都能跑Solr.而网络编程框架的选用直接决定了其高并发的能力。像我们目前项目中数据量限制在GB级别上,ES的PB级数据支持我们用不上,甚至在特定场景下,都无需分词,很少的索引,只做存储,以时间换空间,其实Solr如果解决了IO读写性能瓶颈的问题,更能发挥其优势。话说咱也是做过socket编程的,除了上面说的直接用socket发UDP广播来做配置管理健康检查,在离线服务里我还用http请求直接用浏览器作为客户端,指定一个端口绑定一个socketServer,用ScheduledExecutorService以固定时延用accept方法接收有没有搜索那边兄弟发过来的补发消息请求。如果有,就将socket的inputstream解析处理后写的返回结果到outputstream。虽然写代码是超级简单了,而且是阻塞请求,要不是因为是手动补发数据用的肯定有并发问题。但是足以说明咱也是知道socket编程原理的,只是…… 这个水平就暂时不考虑做自己的网络编程框架了。
IO其实和socket编程是两个概念。IO是socket编辑必须要考虑的问题之一,IO不仅在网络中有,文件系统中也要考虑。所以他们的关系是这样:
当然,其实维度要多的多,维度上的节点也多的多。我总是试图将脑子里的东西表现出来,其实说起来挺简单的。各种不同的维度都是网络编程框架要考虑的问题。netty和mina都是网络编程框架,jetty和tomcat更多被称为web容器。但是他们都主要解决和客户端通信的问题。因为socket编程更接近于底层,需要自己去解决IO的问题,自己去决定用阻塞还是非阻塞,所以常将他们连在一起说。
阻塞的IO,在我做过的socket编程里都表现的很清楚了。打开一个连接一直阻塞在那里到accept到数据处理后关闭。accept就是"我住长江头,君住长江尾"里日日思君不见君的那个苦苦期盼的人。IO是面向流的,NIO是面向缓存区的,缓冲区本质是个数组,存的是整块的数据,所以又叫面向块的。NIO的基本原理挺好理解的。它包括三个基本要素:选择器Selector,通道channel,缓冲区buffer。看过人家包山楂饼的。山楂被生产线压成山楂片之后,会到一个大盒子里面。一个生产线就是一个通道。一个盒子就是一个缓冲区。搬运工会把这些装满的盒子放到特定的负责将山楂片包成一条一条的工人那里。搬运工是选择器。包山楂片是线程来完成的。选择器接触的工序是向Selector注册通道,SelectionKey (包含属性:interest集合,ready集合,Channel,Selector,可选的附加的对象),通过Selector选择通道,唤醒,关闭。框架就是领班。搬运工对领班说我是负责搬运盒子的(向Selector注册通道), 领班就去看这个搬运工,了解他的特长(interest集合)是搬运,已经搬完上个盒子正在等着搬运下一个盒子(ready集合),要处理的是没包装的山楂片盒子(Channel),知道他的所需SelectionKey属性后,就决定让他搬一个盒子(通过Selector选择通道),于是叫他去搬运(唤醒),看到他送去给到了包山楂片的工人就放心了(关闭)。通道的数据不仅可以取出,还可以放入。放入也是搬运工一盒子一盒子放的。所以选择器也有很多选项:建立连接,就绪,读出,写入。读出和写入一个是服务器端,一个是客户端。都是通过通道来通信。告诉你们一个秘密,小姨家的山楂树都无肥无农药,直接对外出口,但是山楂的压碎过程都是脱了鞋袜用脚踩的。知道之后再也没吃过山楂片。
看,山楂的工作流和NIO是一样的。情商高的郭靖最终能打过智商高的杨康。对别人的用心和关心最终会转化为自己的智慧。而爱一个人要比被爱更幸福。看着一个背景会觉得很像心里的那个人,而“真的是你”多少次依然惊喜。明明是算好了人家几点经过,而见到的时候“好巧啊”依然是那么真心。渐渐的,心里的那个人会变成自己的一部分。发现自己和那个人一样聪明,一样善良。因为爱竟然是那么神奇的东西,它可以打开一个通道,可以知道自己喜欢的人在想什么,会在她需要的时候出现。心灵感应竟然是真的。
今天堵车,估计还要两小时才到公司,所以原谅今天的文章不仅跑题太远,而且基本没在正题上=.=