Skip to content

Instantly share code, notes, and snippets.

项目重构总结(一)

@(工作) ####介绍 项目系统间是通过接口进行业务调用,业务目前分B2C和C2C两种交易模式,不同游戏在相同或者不同的交易模式下,校验、支付、商品交互、发货等业务处理也不一样。这就形成相同场景下不同的业务处理需求。重构前的代码部分采用了工厂模式和抽象工厂方法,但是由于抽象工厂方法的原因导致结构设计特别冗余,编码起来特别繁琐,修改起来更麻烦。重构前还有一个不好的地方是B2C和C2C的校验是放一块的,通过交易模式来划分,但是如果不同游戏的校验不一样的话,很难扩展。

重构

重构后的设计是,按业务划分,通过交易模式和游戏类别来生成相关的交易业务Service,将相同的业务方法写到抽象父类的方法中,抽象父类对外只暴露业务接口方法,这样保证了业务入口的一致性,防止业务方法被部分调用的错误。不同游戏、不同模式的业务方法写到相关的子类中,保证业务方法的特殊性。 拿下单校验举例,代码如下:

public class TradeFactory {

项目重构总结(二)

@(工作) ####介绍 接上篇,上次重构后的设计是,按业务划分,通过交易模式和游戏类别来生成相关的交易业务Service,将相同的业务方法写到抽象父类的方法中,抽象父类对外只暴露业务接口方法,这样保证了业务入口的一致性,防止业务方法被部分调用的错误。不同游戏、不同模式的业务方法写到相关的子类中,保证业务方法的特殊性。

问题

但是由于需要接入营销平台SP系统,SP系统又有各种各样的业务、活动,对交易业务逻辑要求不尽相同,上次重构后的系统要想满足SP系统的多态化交易模式,必须为每个业务处理重新写一整套交易流程,包括下单、支付、发货等,这样会使工作量大增,而且不好维护,同时在工厂中新增一遍实现类,感觉不是很灵活。上周根据这种需求又重新设计了一下交易系统设计。

重构

交易系统还是按业务Business来划分(下单、支付、发货、打款等),但是将原来的业务实现拆分成多个“原子方法”Action,每个Action下可以包含多个子Action;单个业务的实现是将“原子方法”Action进行排序组合,相同业务但不同处理就可以选择不同的Action和组合方式;当新增一种业务处理时,只是新增Action,同时可复用原来的Action,大大减少了代码量,并且增加了灵活性。目前这些Business和Action都是可配置的,可根据业务进行不同配置。 如下图

MongoDB数据迁移

@(mongodb)[数据迁移]

主要使用mongodump和mongorestore命令,我把迁移工作分为以下操作: - 先查询现有MongoDB数据库的数据量,目的是比对迁移后的数据量,查看用户数据有没有丢失。 我用了比较笨的方法进行查询,由于我确信不会有新数据插入,所以我直接查询集合文档数量:
db.库名.集合名.count() - 创建所用目录:有MongoDB导出目录和新的数据存储目录。 在新的磁盘上创建文件夹,使用mkdir命令,目录结构要确定好,便于以后维护:

MongoDB中MapReduce的使用

@(mongodb)[mapreduce]

介绍

MapReduce是一个编程模型,封装了并行计算、容错、数据分布、负载均衡等细节问题。MapReduce实现最开始是映射map,将操作映射到集合中的每个文档,然后按照产生的键进行分组,并将产生的键值组成列表放到对应的键中。化简(reduce)则是把列表中的值化简成一个单值,这个值被返回,然后再次进行键分组,直到每个键的列表只有一个值为止。

代码实现(部分重要代码)

例如有一文档user,结构如下:

{

MapReduce任务的执行总流程

@(Hadoop)[mapreduce]

介绍

在main()函数中写入JobClient.runJob(conf),然后将程序提交到Hadoop上,一个MapReduce作业就可以在Hadoop上运行,一个作业的执行流程是:代码编写->作业配置->作业提交->Map任务的分配和执行->处理中间结果->Reduce任务的分配和执行->作业完成,而在每个任务的执行过程中,又包含输入准备->任务执行->输出结果。流程图如下: z-1437461403590.png
从图中可以看出MapReduce作业的执行可以分为11个步骤,涉及到4个独立的实体。它们在MapReduce执行过程中的主要作用是:

  • 客户端:编写MapReduce代码,配置作业,提交作业。
  • JobTracker:初始化作业、分配作业,与TaskTracker通信,协调整个作业的执行;

遇到的问题

####1. MAVEN更新依赖包问题 在包版本号相同且你本地已经有相应的jar包,此时clean install自己的工程是不会更新已有且版本号相同的jar的,应添加强制更新参数: clean install –U

####2. Hessian使用BigDecimal问题** 使用hessian远程调用对象时,如果对象中包含BigDecimal属性,则得到的值会是0。解决方法:
在 hessian.jar 的 META-INF/hessian 目录下加入 serializers 和 deserializers 这两个文件, 两个文件的内容分别如下: java.math.BigDecimal=com.caucho.hessian.io.StringValueSerializer
java.math.BigDecimal=com.caucho.hessian.io.BigDecimalDeserializer

Rainbow Table

@(Web安全)[rainbow]

介绍

彩虹表是一个预先计算好的,用于破解hash密码的文件。它和暴力破解相比,使用更大的存储空间,但是破解时间较短;和简单的散列查找相比,使用时间较长,但是存储空间少。

背景

起初人们可以通过字典穷举的方法进行破解,这对简单的密码是可行的,但是对于复杂的密码,则会产生无穷大的字典,为了解决字典大小,减少产生和查找字典的时间,所以采用了哈希链接的方式用于存储字典。

原理

彩虹表存储预先计算好的hash chain。例如 P代表可能的密码集合,Q是hash后的集合,即Q=H(P);

Nutch介绍

@(Xcaspar)[nutch]

介绍

Nutch是一个爬虫和检索于一体的一个可扩展、高性能的框架。目前有两种版本:最新的分别是v1.8和v2.2.1,两者的区别是底层存储不同,1.X版本基于Hadoop(目前1.2.0版本)架构的,底层存储使用HDFS文件系统。而2.x采用Apache的Apache Gora ORM框架进行存储访问,支持HBase、MySQL等。 两者都有个共同点:必须自己编译源码文件。
说到编译,Nutch是Apache的一个项目,所以项目的编译也是采用自己的ant进行build,jar包管理使用ivy。项目编译还算简单,大体步骤如下:

  • 由于下载的包中缺少代码质量检查的sonar包,但是build.xml文件涉及到,所以,你要自己下载sonar-ant-task jar包,然后更改build.xml中涉及到sonar task的classpath,将地址指向包的位置,比如:
  • 然后ant,此阶段所需时间较长。
  • build之后,默认会有个runtime文件夹,里面包含deploy和local文件夹,分别是部署和本地运行nutch和crawl文件以及相应的配置文件。

Nginx负载均衡机制

@(服务监控)[nginx]

nginx的upstream目前支持以下几种方式的分配 - 轮询(默认) 每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除。

  • weight 指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况。好的服务器weight高些,差的服务器weight低些。