1.2.2. 公共基础依赖包
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>spring-cloud-iiford</artifactId> <groupId>com.github.hashjang</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>spring-cloud-iiford-common</artifactId> <properties> <guava.version>30.1.1-jre</guava.version> <fastjson.version>1.2.75</fastjson.version> <disruptor.version>3.4.2</disruptor.version> <jaxb.version>2.3.1</jaxb.version> <activation.version>1.1.1</activation.version> </properties> <dependencies> <!--内部缓存框架统一采用caffeine--> <!--这样Spring cloud loadbalancer用的本地实例缓存也是基于Caffeine--> <dependency> <groupId>com.github.ben-manes.caffeine</groupId> <artifactId>caffeine</artifactId> </dependency> <!-- guava 工具包 --> <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>${guava.version}</version> </dependency> <!--内部序列化统一采用fastjson--> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>${fastjson.version}</version> </dependency> <!--日志需要用log4j2--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-logging</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-log4j2</artifactId> </dependency> <!--lombok简化代码--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> <!--log4j2异步日志需要的依赖,所有项目都必须用log4j2和异步日志配置--> <dependency> <groupId>com.lmax</groupId> <artifactId>disruptor</artifactId> <version>${disruptor.version}</version> </dependency> <!--JDK 9之后的模块化特性导致javax.xml不自动加载,所以需要如下模块--> <dependency> <groupId>javax.xml.bind</groupId> <artifactId>jaxb-api</artifactId> <version>${jaxb.version}</version> </dependency> <dependency> <groupId>com.sun.xml.bind</groupId> <artifactId>jaxb-impl</artifactId> <version>${jaxb.version}</version> </dependency> <dependency> <groupId>org.glassfish.jaxb</groupId> <artifactId>jaxb-runtime</artifactId> <version>${jaxb.version}</version> </dependency> <dependency> <groupId>com.sun.xml.bind</groupId> <artifactId>jaxb-xjc</artifactId> <version>${jaxb.version}</version> </dependency> <dependency> <groupId>javax.activation</groupId> <artifactId>activation</artifactId> <version>${activation.version}</version> </dependency> </dependencies> </project>
1. 缓存框架 caffeine 很高效的本地缓存框架,接口设计与 Guava-Cache 完全一致,可以很容易地升级。性能上,caffeine 源码里面就有和 Guava-Cache, ConcurrentHashMap,ElasticSearchMap,Collision 和 Ehcache 等等实现的对比测试,并且测试给予了 yahoo 测试库,模拟了近似于真实用户场景,并且,caffeine 参考了很多论文实现不同场景适用的缓存,例如:
- Adaptive Replacement Cache:http://www.cs.cmu.edu/~15-440/READINGS/megiddo-computer2004.pdf2.Quadruply-segmented LRU:http://www.cs.cornell.edu/~qhuang/papers/sosp_fbanalysis.pdf
- 2 Queue:http://www.tedunangst.com/flak/post/2Q-buffer-cache-algorithm
- Segmented LRU:http://www.is.kyusan-u.ac.jp/~chengk/pub/papers/compsac00_A07-07.pdf
- Filtering-based Buffer Cache:http://storageconference.us/2017/Papers/FilteringBasedBufferCacheAlgorithm.pdf
所以,我们选择 caffeine 作为我们的本地缓存框架
参考:https://github.com/ben-manes/caffeine
2. guava
guava 是 google 的 Java 库,虽然本地缓存我们不使用 guava,但是 guava 还有很多其他的元素我们经常用到。
参考:https://guava.dev/releases/snapshot-jre/api/docs/
3. 内部序列化从 fastjson 改为 jackson
json 库一般都需要预热一下,后面会提到怎么做。 我们项目中有一些内部序列化是 fastjson 序列化,但是看 fastjson 已经很久没有更新,有很多 issue 了,为了避免以后出现问题(或者漏洞,或者性能问题)增加线上可能的问题点,我们这一版本做了兼容。在下一版本会把 fastjson 去掉。后面会详细说明如何去做。
4. 日志采用 log4j2
主要是看中其异步日志的特性,让打印大量业务日志不成为性能瓶颈。但是,还是不建议在线上环境输出代码行等位置信息,具体原因以及解决办法后面会提到。由于 log4j2 异步日志特性依赖 disruptor,还需要加入 disruptor 的依赖。
参考:
5. 兼容 JDK 9+ 需要添加的一些依赖
JDK 9之后的模块化特性导致 javax.xml 不自动加载,而项目中的很多依赖都需要这个模块,所以手动添加了这些依赖。
1.2.3. Servlet 微服务公共依赖
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>spring-cloud-iiford</artifactId> <groupId>com.github.hashjang</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>spring-cloud-iiford-service-common</artifactId> <dependencies> <dependency> <groupId>com.github.hashjang</groupId> <artifactId>spring-cloud-iiford-common</artifactId> <version>${project.version}</version> </dependency> <!--注册到eureka--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <!--不用Ribbon,用Spring Cloud LoadBalancer--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-loadbalancer</artifactId> </dependency> <!--微服务间调用主要靠 openfeign 封装 API--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> <!--resilience4j 作为重试,断路,限并发,限流的组件基础--> <dependency> <groupId>io.github.resilience4j</groupId> <artifactId>resilience4j-spring-cloud2</artifactId> </dependency> <!-- https://mvnrepository.com/artifact/io.github.resilience4j/resilience4j-feign --> <dependency> <groupId>io.github.resilience4j</groupId> <artifactId>resilience4j-feign</artifactId> </dependency> <!--actuator接口--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <!--调用路径记录--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-sleuth</artifactId> </dependency> <!--暴露actuator相关端口--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <!--暴露http接口, servlet框架采用nio的undertow,注意直接内存使用,减少GC--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-undertow</artifactId> </dependency> </dependencies> </project>
这里面相关的依赖,我们后面会用到。
1.2.4. Webflux 微服务相关依赖
对于 Webflux 响应式风格的微服务,其实就是将 spring-boot-starter-web
替换成 spring-boot-starter-webflux
即可