标签:href 优化 pom elastics 封装 编码 详细说明 rpc 网络
Spring Cloud 官方文档说了,它是一个完整的微服务体系,用户可以通过使用 Spring Cloud 快速搭建一个自己的微服务系统。那么 Spring Cloud 究竟是如何使用的呢?他到底有哪些组件?
spring-cloud-commons
组件里面,就有 Spring Cloud 默认提供的所有组件功能的抽象接口,有的还有默认实现。目前的 2020.0.x (按照之前的命名规则应该是 iiford),也就是spring-cloud-commons-3.0.x
包括:
DiscoveryClient
,从注册中心发现微服务。ServiceRegistry
,注册微服务到注册中心。LoadBalancerClient
,客户端调用负载均衡。其中,重试策略从spring-cloud-commons-2.2.6
加入了负载均衡的抽象中。CircuitBreaker
,负责什么情况下将服务断路并降级然后,一般一个完整的微服务系统还包括:
在之前的系列中,我们将 Spring cloud 升级到了 Hoxton 版本,组件体系是:
并且实现了如下的功能:
注册中心相关:
微服务实例相关:
metamap
中的zone
配置,来区分不同集群的实例。只有实例的metamap
中的zone
配置一样的实例才能互相调用。网关相关:
metamap
中的zone
配置鉴别所处集群,仅把请求转发到相同集群的微服务实例在后续的使用,开发,线上运行过程中,我们还遇到了一些问题:
接下来,我们要对现有依赖进行升级,并且对现有的功能进行一些拓展和延伸,形成一套完整的 Spring Cloud 微服务体系与监控体系。
本次项目代码,请参考:https://github.com/HashZhang/spring-cloud-scaffold/tree/master/spring-cloud-iiford
这次我们抽象出更加具体的各种场景的依赖。一般的,我们的整个项目一般会包括:
为何微服务要抽象分离出响应式的和传统 servlet 的呢?
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.4</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>com.github.hashjang</groupId>
<artifactId>spring-cloud-iiford</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<properties>
<project.version>1.0-SNAPSHOT</project.version>
</properties>
<dependencies>
<!--junit单元测试-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<!--spring-boot单元测试-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--mockito扩展,主要是需要mock final类-->
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-inline</artifactId>
<version>3.6.28</version>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>2020.0.2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.1</version>
<configuration>
<!--最好用JDK 12版本及以上编译,11.0.7对于spring-cloud-gateway有时候编译会有bug-->
<!--虽然官网说已解决,但是11.0.7还是偶尔会出现-->
<source>11</source>
<target>11</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
<?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 参考了很多论文实现不同场景适用的缓存,例如:
所以,我们选择 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 不自动加载,而项目中的很多依赖都需要这个模块,所以手动添加了这些依赖。
<?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>
这里面相关的依赖,我们后面会用到。
对于 Webflux 响应式风格的微服务,其实就是将 spring-boot-starter-web
替换成 spring-boot-starter-webflux
即可
参考:pom.xml
Spring Cloud 升级之路 - 2020.0.x - 1. 背景知识、需求描述与公共依赖
标签:href 优化 pom elastics 封装 编码 详细说明 rpc 网络
原文地址:https://www.cnblogs.com/zhxdick/p/14615594.html