车险项目总结

前言

一个有点久的项目,前不久做的前后端分离,虽然相比较技术还是有点落后,很小白,还是总结一下,毕竟路还是得一步步的走。

后台:

  1. 系统整体架构是spring+springMVC、持久层是mybatis、连接池之前是c3p0后来连接池老是挂就换成了HikariCP
  2. 服务器是tomcat、使用了开源项目tomcat-redis-session-manager持久化session到redis集群.
  3. 由于并发不高后台服务器就2台,项目过程中调用外部系统接口的地方很多,所以spring集成了zookeeperdubbo缓解调用外部接口的负载.
  4. 公司系统很多JNDI配置方面集成了disconf

前台:

  1. 前台服务器nginx、技术属于刀耕火种的时代,jquery一撸到底。

打包工具:ANT

因为这个项目工程包含三个子项目(客户系统、定时任务、后台),开发的时候这三个项目关联性强,所以在一个工程里面也方便开发。
有篇文章写的挺好的传送门

配置文件:JNDI

由于properties文件会因服务器环境或其他场景需要改动,是放在tomcat的conf目录下,具体可以使用spring的BeanFactoryPostProcessor类来进行加载,在XML文件中用${key}或者需要在相应的类文件中编写该key的setter方法,spring就会注入值了,具体代码如下:

1
2
3
4
5
6
7
8
9
10
11
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="order" value="1" />
<property name="ignoreUnresolvablePlaceholders" value="true" /><!-- 忽略不可解析的 Placeholder -->
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" /><!-- 可以从jvm虚拟机的参数中获得配置信息 -->
<property name="ignoreResourceNotFound" value="true" /><!-- 忽略未找到的资源 -->
<property name="locations">
<list>
<value>file:${confPath}/jndi.properties</value>
</list>
</property>
</bean>

其中confPath变量是在tomcat的context.xml添加的环境变量,如:

1
<Environment name="confPath" value="${catalina.home}/conf" type="java.lang.String" override="false" />

后来由于服务器环境太多以及项目配置文件也增多,每次配置调整起来都比较麻烦,还容易出错,所以AMC系统与disconf系统做了深度整合,提供集中式配置管理服务,基于zookeeper实现对配置更改的实时推送,配置更改自动reload,需要在servlet.xml中添加一下代码,如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<context:component-scan base-package="com.baidu" />
<aop:aspectj-autoproxy proxy-target-class="true" />
<context:annotation-config />
<bean id="disconfMgrBean" class="com.baidu.disconf.client.DisconfMgrBean" destroy-method="destroy">
<property name="scanPackage" value="com.baidu.disconf" />
</bean>
<bean id="disconfMgrBean2" class="com.baidu.disconf.client.DisconfMgrBeanSecond"
init-method="init" destroy-method="destroy">
</bean>
<bean id="configproperties_disconf" class="com.baidu.disconf.client.addons.properties.ReloadablePropertiesFactoryBean">
<property name="locations">
<list>
<value>jndi.properties</value>
</list>
</property>
</bean>
<bean id="propertyConfigurer_disconf" class="com.baidu.disconf.client.addons.properties.ReloadingPropertyPlaceholderConfigurer">
<property name="ignoreResourceNotFound" value="true" />
<property name="ignoreUnresolvablePlaceholders" value="true" />
<property name="propertiesArray">
<list>
<ref bean="configproperties_disconf" />
</list>
</property>
</bean>

那么业务系统如何连接AMC?
需要在项目的classpath(源文件下或者src下)路径下添加两个文件名字必须一样(disconf.properties、disconf_sys.properties)。
disconf_sys.properties文件内容说明如:

1
2
3
4
5
6
7
8
#获取配置文件根节点
disconf.conf_server_store_action=/api/config
#获取zookeeper地址
disconf.conf_server_zoo_action=/api/zoo
#获取远程主机个数的URL
disconf.conf_server_master_num_action=/api/getmasterinfo
# 下载文件夹, 远程文件下载后会放在这里
disconf.local_download_dir=/opt/server/conf

disconf.properties文件内容即说明如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#是否从云端下载配置
disconf.enable.remote.conf=true
#忽略哪些分布式配置
disconf.ignore=test
#获取远程配置 重试次数,默认是3次
disconf.conf_server_url_retry_times=3
#获取远程配置 重试时休眠时间,默认是2秒
disconf.conf_server_url_retry_sleep_seconds=2
#让下载文件夹放在 classpath目录 下
disconf.enable_local_download_dir_in_class_path=true
#配置文件服务器 HOST
disconf.conf_server_host=10.0.0.0
#版本
disconf.version=1_0_0
#系统名称
disconf.app=amc
#部署环境
disconf.env=sit
#用户指定的 下载文件夹, 远程文件下载后会放在这里
disconf.user_define_download_dir=/opt/server/conf

当在amc配置管理中心修改了jndi.properties配置文件并点更新按钮.项目中bean的属性值就修改了不用重启项目。
注:项目一部分托管disconf管理,一部分spring管理的时候,spring管理的配置一定要写在disconf管理配置之后

连接池:HikariCP

spring配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource"
destroy-method="shutdown">
<constructor-arg>
<bean class="com.zaxxer.hikari.HikariConfig">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="jdbcUrl" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<property name="connectionTestQuery" value="${hikaricp.connectionTestQuery}" />
<!-- 等待连接池分配连接的最大时长(毫秒),超过这个时长还没可用的连接则发生SQLException, 缺省:30秒 -->
<property name="connectionTimeout" value="${hikaricp.connectionTimeout}" />
<!-- 一个连接idle状态的最大时长(毫秒),超时则被释放(retired),缺省:10分钟 -->
<property name="idleTimeout" value="${hikaricp.idleTimeout}" />
<!-- 一个连接的生命时长(毫秒),超时而且没被使用则被释放(retired),缺省:30分钟,建议设置比数据库超时时长少30秒 -->
<property name="maxLifetime" value="${hikaricp.maxLifetime}" />
<!-- 连接池中允许的最大连接数。缺省值:10;推荐的公式:((core_count * 2) + effective_spindle_count) -->
<property name="maximumPoolSize" value="${hikaricp.maximumPoolSize}" />
<property name="minimumIdle" value="${hikaricp.minimumIdle}" />
<property name="leakDetectionThreshold" value="${hikaricp.leakDetectionThreshold}" />
</bean>
</constructor-arg>
</bean>

我的配置文件如下:

1
2
3
4
5
6
7
8
9
10
jdbc.url=url
jdbc.username=username
jdbc.password=password
hikaricp.connectionTestQuery=SELECT 1 FROM DUAL
hikaricp.connectionTimeout=300000
hikaricp.idleTimeout=600000
hikaricp.maxLifetime=1800000
hikaricp.maximumPoolSize=1
hikaricp.minimumIdle=1
hikaricp.leakDetectionThreshold=20000

tomcat-redis-session-manager持久化session到redis集群

1、添加redisson-all-2.9.2.jar 和 redisson-tomcat-8-2.9.2.1.jar
2、修改tomcat的conf下context.xml:
删除 <Valve className="com.orangefunction.tomcat.redissessions.RedisSessionHandlerValve" />并增加如下:

1
2
3
<Manager className="com.orangefunction.tomcat.redissessions.RedisSessionManager"
maxInactiveInterval="600" sentinelMaster="${redis.sentinelMaster}"
password="${redis.password}" sentinels="${redis.sentinels}" />

3、在catalina.properties中添加如下:

1
2
3
redis.sentinelMaster=master
redis.password=testpw
redis.sentinels=10.100.40.000