项目变迁之一--初始

15年8月,离开原有公司,开始了跟几个并不合适创业的人一起创业,个中酸甜苦辣,难为人知。创业方向是城际定制化出行,我整体负责技术相关,项目从单一的系统满足唯一需求,慢慢演化到了多个系统之间的协作,也开始引入了一些中间件.在这里记录下,也算是补充下自己的知识库.

最初

刚开始诉求很简单,就只是单系统,然后提供一系列简单的http restful接口给APP端,所以采用了最基础一些框架配置:

配置文件:
  • WEB-INF下的配置,除了web.xml外,就只有一个springmvc对应的servlet.xml


    QQ图片20160830170938.png
  • resources下的配置文件,根据功能拆分了spring相关的配置(先暂时忽略ini及properties文件哈,后续会有说明).


    项目变迁之一--初始_第1张图片
    QQ图片20160830170956.png
web.xml

主要配置了spring及springmvc相关信息,如下:

    
   contextConfigLocation    
   classpath*:spring.xml


    
   characterEncodingFilter    
   org.springframework.web.filter.CharacterEncodingFilter    
           
         encoding        
         UTF-8    
       
           
        forceEncoding        
        true    
   

    
     characterEncodingFilter    
     /*
 

     
    springmvc-servlet    
    org.springframework.web.servlet.DispatcherServlet    
                 
            contextConfigLocation        
            /WEB-INF/spring-servlet.xml    
             
    1
 

     
       springmvc-servlet    
       /

spring

核心框架spring,用于管理所有的bean及其之间的注入,并处理与数据库的事务(使用注解).

  • 最初采用spring2.5.6,比较老也比较稳定的版本.

  • 事务采用@Transactional注解来完成,避免配置一堆xml文件.

  • 在spring配置文件中配置扫描路径:

springmvc

对外提供的接口采用springmvc,一方面是与spring的无缝集成,另一方面确实很简单,提供了注解,也支持json等数据格式的自动映射及处理.

  • springmvc配置比较简单,只需要一个-servlet.xml即可,也支持controller及方法级别的注解.servlet.xml文件如上图所示,放在web.xml相同路径下。
    不过需要注意的是,这里的注解扫描包的设置会与上面spring注解扫描包的配置产生冲突,造成事务不生效的情况,所以需要排除事务控制层。在
    servlet.xml中配置如下:



    也就是排除对@Service注解文件的扫描。相应的,事务控制层的bean,全都使用@Service来标注。

  • 框架本身就支持集成jackson,不需要自己处理json与model的转换,这个相当方便。

  • jackson框架支持Model的注解,对于不需要转换的属性及空值属性,均可通过注解来完成,另外jackson在处理json序列化与反序列化时的性能很好,推荐使用.

持久化层

ORM层采用ibatis,sql可以自己控制,也相对灵活.数据库连接池采用了bonecp.

  • 由于ibatis默认的配置就开启了缓存,其他的一些配置其实也并不需要,故省掉了ibatis的配置文件,以及dao层,直接使用mapper.xml与对应的mapper.java来实现与DB结构的映射.(注意mapper.xml与Mapper.java一定要在相同的包名下,而且要相同名称,比如Mapper.java所在路径:
项目变迁之一--初始_第2张图片
Paste_Image.png

mapper.xml所在路径

项目变迁之一--初始_第3张图片
Paste_Image.png

  • 对应的spring配置如下:


  • bonecp号称最快的数据库连接池,当然后面发现其实并不然,且存在一些其他问题,而且很早之前就停止更新了,这个后面详细说下。数据库连接池的配置网上一堆,这里就不贴出来了,O(∩_∩)O~

  • 数据库用了免费强大的mysql V5.6版本,UTF-8字符集,innoDB引擎(支持事务,且只锁行,而不像myIsam不支持事务,且会锁整张表,而且也不支持外键;关于innoDB和myIsam的对比可以参考这里:http://www.dedecms.com/knowledge/data-base/mysql/2012/0819/7217.html ),单库存储.

其他
  • 与APP端的交互采用json数据格式,无论是客户端,还是服务端,或者原生支持,或者存在比较好的第三方框架.在spring-servlet.xml中配置如下:







    text/html; charset=UTF-8
    application/json;charset=UTF-8





  • 部分数据的处理(比如订单未付款超时)采用基于quartz1.8.6框架的定时任务.
  • 使用logback日志框架,log4j作者的新作,性能更好,并发场景下做了不少日志相关的优化。关于logback和log4j的对比可以参考这里:http://www.cnblogs.com/james1207/archive/2013/09/15/3323106.html
  • 基于maven3做依赖管理.Git做代码版本控制.(coding.net还是不错的,推荐下,国内基本上没找到更易用的)
  • 基于Ubuntu14.04-PC搭建了一个测试服务器,线上采用2台阿里云服务器(CentOS6.3).
  • 使用nginx1.4.6做负载均衡及端口反向代理,后端采用双tomcat7做Web服务器.

第一个版本基本上就是如此,两个人快速开发,耗时一个半月,加上与客户端的调试时间,在双十一前后正式上线,慢慢的客户端开始推广,也开始有些数据过来,初始版本算是基本满足需要。

慢慢的发现第一版是存在一些问题的,包含代码层面和环境问题:

  • CentOS自带了openJDK,Ubuntu则是安装了JDK1.7,部分功能在测试环境OK,部署到线上就存在问题.
  • 代码全都在同一个系统中,业务发展要求有一个管理后台,包含部分调度相关的处理,不管是管理后台还是前端接口,哪个部分发生变动都会影响到另一端.
  • 某些场景下事务回滚失败,造成了部分脏数据。
  • 定时任务的代码同时在线上两台服务器上运行,本身就造成了并发导致的脏数据.
  • 数据库一直是单库操作,无备份,中间出现一次DB所在服务器宕机的情况,造成将近1个小时的服务不可用,对数据安全的要求提上了日程.
  • 部分接口需要APP端频繁轮询调用,对用户手机的资源占用和后台HTTP接口都是一种并不友好的处理方式.

针对以上问题,产生了项目2.0版本,主要改动如下:

  • 统一设置线上及测试环境下的JDK为1.8版本,废弃OpenJDK.
  • 使用nexus搭建maven私服。
  • @Transactional注解设置rollback条件,并针对业务异常做回滚操作.另外注意,此注解在非public方法上并不生效.
  • 做系统拆分,将原有系统拆分为management及platform两个系统,并有一个独立存在的common模块(后又合并到platform系统中),用于承载数据库domain及mapper文件,以及一些工具类和model
  • quartz加入集群配置,数据库加入qrtz库并设置定时任务的集群配置.
    详细的改动会在下面的章节一一给出。

你可能感兴趣的:(项目变迁之一--初始)