DevilKing's blog

冷灯看剑,剑上几分功名?炉香无需计苍生,纵一穿烟逝,万丈云埋,孤阳还照古陵

0%

作为第一次去参加这种级别的会议,心里还是有些期待,不过由于时间点不好,只是听最后一天的演讲,回来之后也就是大抵如此的感觉,一半扯淡一半干货吧。

首先是雪球网的node.js的相关的分享。对于node.js,自己基本不熟悉,但这场演讲居然也能听的进去,果然是入门级的(对于另一些的node.js来说是不是过于入门级。。)。node.js出现的背景在于前端工程师对于仅仅学习html/js一套,对于去写jsp页面的不满,去配合后端java写业务的不满,于是前端工程师也可以用写js的方式来写后端。这里面,谈到的一个很关键一点是,node可以兼容之前的做法,即:一、用ajax的方式去获取后端数据,二、用js去拼接json数据。个人觉得这两个关键点是促成node.js发展的一个很关键的因素。而后,分享举了一些实际的工作编程中以及迁移中遇到的问题。如,node也有相关的模板语言,如何选择好的模板语言,这里提到了**[mustache][1]**,它是一种支持多种语言的轻量级的模板语言,所谓轻量级,应该是指其支持json数据尤其出色;js中也有异常处理,针对这部分的异常,如何去抓住,这里提到了 uncaughException;针对异常的抛出,node采用的是一层抛一层的方式(是不是跟java中的抛出异常不一样?),也就是上层对下层抛出的异常是透明,这样必然会带来多种嵌套的问题;最关键的是node的实际生产环境必然会有大量的并发请求的问题,这样一种并发执行会带来什么样的问题,如何去避免这样的问题?最后是相关的一个总结,

  • 如找到靠谱的错误处理,针对node的异常抛出问题,不能简单的抛出;
  • 全局变量和局部变量的区分问题,这里举的是var的例子,分享者针对这一点讲到他们的命名规则是内存变量加上_,不过个人觉得,难道前端工程师对于全局和局部变量的区分度很差吗?为什么会出现缺var这样的错误?不过这样的命名规则可以用来考虑。
  • 打日志是很好的调试工具,简单可靠。

技术上的分享大抵如此,不过在演讲过程中,一个很有意思的思路是将雪球网将某些人的言论跟金融趋势图去联系在一起,从而来验证实际的发展跟当时的言论是否匹对,将足彩的那一套沿用到金融里,而且更进一步用图标增长的方式,比足彩更形象。

然后是听了一下有道云笔记的云端架构。其实对于云端架构这个东西,其架构图基本沿用GFS那套,还是依旧的三方的架构。只不过,这里提到的笔记的需求是,1、随时编辑,2、历史版本查阅,3、协同,分享。于是,原来针对数据部分的频繁修改操作扩展到meta数据上,通过meta的数据的修改,以及对应到不同的meta数据来实现相关的笔记的需求。这种思路,类似于linux的软链接的方式。这里,说一下觉得很有意思的几个点:

  • 随着移动设备的兴起,笔记方面有移动端的需求,这在之前的分布式的框架中没有想到过的。于是,笔记方面,增加了一层协议分析层,遵从不同的设备使用不同的api的方式,虽然pc端和手机端看到的内容是相同的,但其内部的api处理的方式是不同。例如,pc端,可以采用一块一块读取的方式呈献给用户信息,meta数据的处理也可以部分放在客户端来进行,但在移动端,就不行,需要全文完整地传递完后呈献给用户,并且相关的meta的处理也会随着内容一起上传回去。也就是,底层的数据相同,但针对不同的端,其处理、读取的方式是完全不同的。
  • 针对笔记,免不了并行操作,这就要考虑相关的操作隔离。这里在我们平常所谓的数据锁的基础上再加一层,剔除逻辑数据块锁,其仅保证对同一数据的操作分发到同一个逻辑存储模块,这样我们不用直接跟底层的数据块打交道,只需对我们所设计的逻辑数据块来操作,这样带来的好处也是明显的,逻辑数据块的大小和相关的锁操作是我们可以自定义的,灵活。
  • 底层云这块,架构方面依然是文件系统那套的规则,果然是,越底层,其大变化的周期越长,而这里更需要上层所谓的微创新,需要你根据特定的环境所做的一点小的变化。其实对于java这种企业级的框架以及语言来说,这个道理也是说的通的。

第三场的演讲则是jboss云方面,这场基本在扯淡,首先扯了一大堆的构建企业混合云的必要性和背景,然后是介绍其所在jboss团队推出的as7。这里有意思的一点是,云针对多租户应用架构的变化。这里提到了针对这种情况,会出现两种对象,一是有状态的对象,这种通过调用者和应用名称可以锁定,另一种就是无状态的对象,需通过传递两个以上的信息来锁定。这里的思路,可以用在icafe的流程引擎中,针对action方面,也存在有状态的action和无状态的action,所以这块的多租户应用架构,可以去考虑实现在icafe的流程引擎中。

最后一场的演讲则是ebay的下一代数据集成平台的介绍,其核心在于介绍ETL,即这种用在数据仓库中,去萃取和提取相关的信息,而ebay方面则用在日志的抽取和转置上。这个跟上周oracle的那个bi系统很类似,一样也是利用ETL来转置数据。这里讲几点:

  • 类似这种日志处理的程序来说,其需要考虑多种数据源的流入,例如,需要多个数据库的多张表的情况,所以关于数据源的配置必须是灵活多变的,
  • 由于数据源的灵活多变,所以其处理过程也是千变万化,于是,提出了
ETL ID specific State files
```,这个是实现所谓的metadata driven everything的基础。这里的ETL metadata是指,ETL过程中的workload, data lineage, ETL Job State, Resource tracking and metrics等。通过这些信息,我们可以了解这次ETL的所有信息。
*	定期的对metadata进行collection操作,分析其中的信息,例如,可以统计每张表的使用频度,方便我们进行数据的合理化处理。

可能ETL方面更加不为人所知,最后一场涉及到的名词也是所有听到的演讲中所涉及到的专有名词也是最多的。像什么VDM,TDWI等。不过,其ETL的过程很类似icafe的流程引擎部分,只不过有一点很重要的是,icafe关于数据的层次的划分很不明显,虽然有很多的表,但表之间的关系,并没有层次关系,没有很强的metadata的特征,这块可以在后面进行加强和改造。

基本上,四场演讲听下来,人也有些疲倦,然后是坑爹的吃中饭环节,会议的自助,尤其针对屌丝程序员这种,基本不够看的。。哎,于是,直接出了会议,跟着另一个路盲的同事,幸亏有百度地图,找到麦当劳,凑合一顿。于是第一次的Qcon之旅over。




[1]: http://mustache.github.io/ "mustache"

话说好几个星期都懒地提笔了,豆瓣上看到一篇“被消失的普通人”,又兴起了提笔的兴趣。

正如一场电影,需要有正义和邪恶的较量,才能激起观众的兴趣。…用力过猛,成为了当下中国的时代病,咱们还能活一阵子呢?能留点劲吗?

而用力过猛的后果之一就是造神,一个人大喊,我找到神了,众人迅速围拢,举手欢呼。然后就是踩神,另一人大喊,丫不是神,于是众人咒骂,哄散而去。不管是中国的媒体还是国外的媒体,都有这样的问题,但为什么用力过猛只是当代中国的,别的没有呢?

只是我还在想,几年前,不管是新闻界还是微博网民,都在嘲笑中国媒体,说它们一遇到天灾就报道“高大全”的典型人物。近一两年,这种手法在一片奚落声势渐弱。然而,可能连宣传部的老爷们都没想到:断了他们的粮,这帮网民竟然开始自给自足起来?

屁民在生活是屌丝,只能期望各种媒体来各种造神,来各种屌丝的逆袭,才能满足活下去的动力,才能聊以自慰,“嗯,自己还有点信仰”,呵呵,一声呵呵代表何止是一声叹息。。

之前在网易体育上,看到自己喜爱的主教练穆里尼奥50岁的专题,一句“知天命”,感觉到莫名的心悸,是啊,穆鸟50岁了,到了知天命的年龄,没有了之前的意气风发,有的只是更衣室的内乱和封杀,没有之前的滑铲庆祝,有的只是无力地嘟恼几句,这还是我心中的那个神吗?神不应该一直在奇迹的顶端,一直在成功的彼岸吗?但这就是现实,神不过是造出来的,只不过现在到了睬神的时候了。

生活总有巅峰和低谷,你的巅峰期享受的越久,那你的低谷期也会遥遥无期。生活是公平的,不过鸟还是我喜欢的鸟,还是我喜欢的自认为特殊的一个,还是我喜欢的与天斗的一个,还是我喜欢的伴随我成长的鸟。谢谢你,穆里尼奥,生日快乐!

每个人都有高峰和低谷,每个人也有成神和被踩的时候,而你所需要做的只是保持一颗本我的心,保持一份淡定的心态。

任门外风吹雨打,我自胜似闲庭信步。坐看庭前花开花落,笑望天边云卷云舒

做好自己,拼命地做好自己暂时觉得正确的事情,或许这才是自己的一份淡定。

前面已经分析了流程引擎的基本构成,而这里的重点主要是为了如何改造这个流程引擎,使之能够完成其既定的两个目标。

  • 能够简单方便地加入流程节点
  • 能够在流程节点的运行过程中触发某些事件

其实流程引擎的目的在于编写一个小bpm,但又不仅仅是一个bpm。针对将现有的流程引擎改造的考虑,可以基于下面几点:

  • 流程渲染部分的改造,将相关的从baseinfo读取的action的信息,可直接通过actioninfo和taskinfo来读取相关的信息
  • icafe需要接管baseinfo的模板内容,即相关的sqaTaskTemplate的内容。这块可参考的思路是,首先,在配置中心部分,新建一个模板类的基础数据结构,即baseinfo的流程活动序列,只不过全部均为默认值;其次,以前的生成相应的taskinfo和actioninfo的逻辑暂时不变,而在流程活动池部分,相关的action基础的内容可由配置中心的内容来读取
  • 这样针对流程节点的加入方面相对简单,在配置中心的基础数据结构中加入相关的action信息,这样在流程活动池部分就可以看到该action,然后选择加入后,即可渲染在模块详情页部分
  • 流程节点的加入是一方面,但是其展示呢?展示部分是否会放在流程导航图上?

整个流程引擎应该分为三个部分,config, context组成构成process的基本部分,template作为整个process串联的基础,生成weavable,然后通过weavable,并辅助相关的scm的状态,最后拼接成一串的process节点,即完成整个流程的渲染过程。

  • 首先config方面,基本存储静态的变量,如key, name, description等,

    • 这里面有一个小技巧,由于config可以有多种的实现方式,于是其接口config只是定义基本的get方法,由各种实现去具体实现get方法,这样其他类来调用的时候,只需调用get方法就有取到相应的静态变量,而不需要特意在接口处定义变量。
      如下面所示

      1
      2
      3
      4
      5
      6
      public interface Config extends Serializable {
      public Integer getId();
      public String getKey();
      public String getName();

      }
  • 关于config的实现,现有2个基本的实现,一是commonConfig,即普通的节点的config,如申请四位版本,模块编译等,主要是scm的操作的一些process;另一种是actionConfig,即由baseinfo定义的一些action转化的process。这里有一个感想,针对我们后面的统一化管理,可以将这两种都归结于actionConfig,申请四位版本和模块编译等,都可以作为action来存储在icafe中,icafe在开发任务task中加入相关的action即可。

  • 然后是template部分。这里的template以baseinfo的模板作为基础,根据不同的任务,进行相关的操作,并生成weavable。这里的weavable,作为一个list,其实已经是简版的流程节点的串联,其包含相应的process的key以及process后需的节点的key和相应的type。

    • 以开发任务的action为例,首先是判断该action是否被裁剪掉了,来判断是否要加入到weavable中去;然后设置相应的weavable的key和weaveType;最后转化相应的action的信息,放入到configMap中去,方便后面调用。

    • 这里重点讲一下addOnline方面。

      • 首先对于上线部分,其作为一个大的task存在,这里有个小技巧,将task转化为action,从而可以同上面的addAction相同的处理
      1
      ActionConfigAdapter config = new ActionConfigAdapter(convert(task));
  • 其次,针对上线方式部分,采用获取从icafe中相关的上线方式,然后将相关action转化为sqaActionTemplate后,作为process的child节点加入到weavable中去.

      
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    for(ActionInfo act : actionInfos){
    String key = ConfigDataUtil.getKeyActionByProcssDefineId(act.getActionDefineid());
    w.setWeaveKey(key);
    w.setWeaveType(WeaveType.CHILD.name());
    weavables.add(w);

    ActionConfigAdapter actConfig = new ActionConfigAdapter(convert(act));
    configMap.put(key, actConfig);

    w = new Weavable();
    w.setKey(pk);
    }

这里有部分不能理解的是上线方式居然是从icafe中获取,而不是从baseinfo中获取。这里影射出icafe同baseinfo之间的关系若即若离,icafe既想同baseinfo切除关系,但是又很多的内容依赖于baseinfo,这层关系还需慢慢梳理,慢慢切除。

  • 完成了template部分的解析,就会得到两个比较重要的变量,即
    List<Weavable> weavablesMap<String, Config> configMap ,前者即为流程串联的list,后者为相关的config信息,后面就是weaver部分,这部分就是将这两者加入scm的一些辅助状态,一起串联成为我们所谓的process串。同样,这个串联过程大致分为三个部分:

    1. context的相关信息的初始化。前面讲到了context里存放着process的上下文环境,这里主要是一些scm的状态。这里拿到的是scmProcessContext,实际上映射着DefaultScmContext(吐槽一句:这个东西能不能相同命名,不然还需要去xml去寻找相应的对应关系,命令的规范遵循的是什么。。。),这里拿到codePath
      codeVersion,以及最重要的Map<String, ScmOperateBean> scmOperates但是,在这个串联的后续步骤中,个人感觉这个东西没有用到。。
    2. 随后便是遍历List<Weavable> weavables结构,首先从相关的configMap依据相应的weavable的key值取得相应的config,然后通过
    1
    process = (Process) applicationContext.getBean(beanName, Process.class);

来初始化相应的process,同时将process加入到Map<String, Process> processMap中。
随后,从processMap中选取第一个节点作为headProcess返回即可。

感想:

  • context这个变量的设计感觉毫无头绪。首先对于scmOperates的初始化,可以放在template的解析中,同样也是属于状态的解析;其次,对于processMap,依然可以放在template的解析中;这样导致就是process中的context变量还有没有意义?

  • 对于processMap的设计初衷是什么?既然是遍历weavables,然后按顺序将生成的process加入到processMap中去,为什么不继续复用weavables,而要另开一个map?

  • 对于SqaTaskTemplateAdapter这个结构的extends关系,感觉不是很理解,为后面的扩展性的需要有什么帮助?直接作为引擎的一个实现,这才是他的核心吧

  • 得到headProcess之后,然后就是processRender的工作。这方面没什么好说的。

至此,整个流程模板的渲染过程大致介绍完毕。下图是流程的介绍说明。

正如编程需要训练一样,写作也需要时常练习,才会写地有条理,有看头。最近,好像有点习惯,在公司里呆上个大半天,去干些自己强制本周完成的活,每次只想着完成一件事情就ok。现在看起来,效果不错,可以持续进行下去。

人果然是矛盾体,一边警戒自己要各种低调,一边想着自己突然有一天成为救世主那么光鲜。有时候觉得自己还是一中二病的患者,有时候不切实际地想着乱七八糟的东西。