微服务概念
微服务是软件的一种现代方法,通过该方法,应用程序代码以可管理的小段形式交付 ,彼此独立。微服务是一种架构或者风格,它提倡将单一应用程序划分为一组小的服务,每个 服务运行在其独立的自己的进程中,服务之间互相协调,互相配合,为用户提供最终价值。
微服务的小规模和相对隔离性可以带来许多其他好处,例如更容易维护,提高生产率,更大的容错能力,更好的业务调整等。
主流框架
Spring Cloud : Spring Cloud是关注全局的微服务协调整理治理框架,它将Spring Boot开发的一个个单体微服务整合并管理起来,为各个微服务之间提供,配置管理、服务发现、断路器、路由、微代理、事件总线、全局锁、决策竞选、分布式会话等等集成服务
Dubbo :是阿里巴巴公司开源的一个高性能优秀的服务框架,使得应用可通过高性能的 RPC 实现服务的输出和输入功能,可以和 Spring框架无缝集成。Dubbo是一款高性能、轻量级的开源Java RPC框架,它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现。
主要技术点
- 服务的注册与发现
- 身份验证与授权
- 服务的伸缩控制
- 反向代理与负载均衡
- 路由控制
- 流量切换
- 日志管理性能度量、监控与调优
- 分布式跟踪
- 过载保护
- 服务降级服务部署与版本升级策略支持
- 错误处理
前情提要
微服务父模块依赖
<?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">
<modelVersion>4.0.0</modelVersion>
<groupId>com.wcy.hand</groupId>
<artifactId>Eureka-Study</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<modules>
<module>Eureka-Client</module> <!--客户端模块-->
<module>Eureka-Server</module> <!--服务端模块-->
</modules>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.5.RELEASE</version>
</parent>
<!--维护版本-->
<dependencyManagement>
<dependencies>
<!--维护spring-cloud版本-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.SR6</version>
<!--以pom版本引入-->
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
微服务组件均配置于子模块中,故无需版本号
Eureka
Spring-Cloud Eureka 是Spring Cloud集合中一个组件,它是对Eureka的集成,用于服务注册和发现。
Eureka是Netflix中的一个开源框架。它和 zookeeper、Consul一样,都是用于服务注册管理的,同样,Spring-Cloud 还集成了Zookeeper和Consul。
Eureka 采用了 C-S 的设计架构。 **Eureka Server 作为服务注册功能的服务器,它是服务注册中心** 。而系统中的其他微服务 使用 Eureka 的客户端连接到 Eureka Server并维持心跳连接 。这样系统的维护人员就可以通过 Eureka Server 来监控系统中各个微服务是否正常运行。Spring Cloud 的一些其他模块(比如Zuul)就可以通过 Eureka Server 来发现系统中的其他微服务,并执行相关的逻辑
Eureka上的服务实例可以分为两种:Eureka Server和Eureka Client。 为了便于理解,我们将Eureka client再分为Service Provider和Service Consumer。Eureka Server 提供服务注册和发现Service Provider 服务提供方,将自身服务注册到Eureka,从而使服务消费方能够找到Service Consumer服务消费方,从Eureka获取注册服务列表,从而能够消费服务
Eureka集群及搭建
Ribbon
Spring Cloud Ribbon 是基于Netflix Ribbon实现的一套客户端负载均衡的工具
简单的说,Ribbon是Netflix发布的开源项目,主要功能是提供客户端的软件负载均衡算法,将Netflix的中间层服务连接在一起。Ribbon客户端组件提供一系列完善的配置项如连接超时,重试等。
简单的说,就是在配置文件中列出 Load Balancer(简称LB) 后面所有的机器,Ribbon会自动的帮助你基于某种规则(如简单轮询,随机连接等)去连接这些机器。我们也很容易 使用Ribbon实现自定义的负载均衡算法
Load Balance
负载均衡(Load Balance),在微服务或分布式集群中经常用的一种应用。
负载均衡简单的说就是 将用户的请求平摊的分配到多个服务 上,从而达到系统的HA。常见的负载均衡有软件Nginx,LVS,硬件 F5等。相应的在中间件,例如:Dubbo和Spring Cloud中均给我们提供了负载均衡 Spring Cloud的负载均衡算法可以自定义 **。
- 负载均衡算法在客户端
- 客户端维护服务地址列表
使用步骤
引入maven依赖
将依赖放在客户端下
<!--包含了Ribbon依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!--在没有使用Eureka的情况下,可以单独添加-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
配置文件
现在的 Ribbon 基本上不需要单独引用,因为绝大多数的注册中心(Eureka,consul等)都会集成它
采用Eureka的配置文件即可
server:
port: 8989
spring:
application:
name: eureka-client
eureka:
client:
service-url:
service-url:
defaultZone: http://localhost:8761/eureka,http://localhost:8762/eureka,http://localhost:8763/eureka
# instance:
# lease-expiration-duration-in-seconds: 10 # 修改eureka server默认接受心跳的最大时间 默认90s
# lease-renewal-interval-in-seconds: 5 # 指定客户端多久向服务端发送一次心跳 默认30s
@LoadBalance注解配置
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
/**
* @author wcy
* @DATE 2022/9/27
*/
@Configuration
public class RestTemplateConfig {
@Bean
@LoadBalanced //开启负载均衡,
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
}
主启动类添加注解
主启动类添加-****@EnableEurekaClient @RibbonClient****
负载均衡策略
配置ribbon负载策略
配置类
配置类不能放在被 @ComponentScan 注解能扫描到的包下,否则将被所有的 ribbon client 共享
如 有A\B\C三种服务,如果ribbon配置类被该注解扫描到了,我们原本只想让A服务自己来遵循该负载策略,结果 我们所有的服务 A B C 全都按照这个策略来执行了,达不到独自配置的目的
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author wcy
* @date 2022/9/27
*/
@Configuration
public class RibbonConfig {
@Bean
public IRule iRule(){
return new RandomRule();//随机策略
}
}
配置生效
在主启动类上添加 ribbon客户端注解
@RibbonClient(name = "PROVIDER-SERVICE",configuration = RibbonConfig.class)
name 是指定哪个服务使用该策略, configuration 是我们写的配置类
@RibbonClients不同于@RibbonClient,它 可以为所有的Ribbon客户端提供默认配置。
@RibbonClients(value = {@RibbonClient(name = "user-service",configuration = NewRuleConfig.class)})
或者
@RibbonClients(defaultConfiguration = DefaultRibbonConfig.class)
设置访问
@Autowired
private RestTemplate restTemplate;
@GetMapping("/users/{id}")
public User findById(@PathVariable Long id) {
// 这里用到了RestTemplate的占位符能力
User user = this.restTemplate.getForObject(
"http://service-name/users/{id}", User.class, id); //用服务名称代替ip
return user;
}
Hystrix
分布式系统面临的问题
复杂分布式体系结构中的应用程序有数十个依赖关系,每个依赖关系在某些时候将不可避免地失败。
多个微服务之间调用的时候,假设 微服务A调用微服务B和微服务C , 微服务B和微服务C又调用其它的微服务 ,这就是所谓的“ 扇出 ”。如果扇出的链路上 某个微服务的调用响应时间过长或者不可用 ,对微服务A的调用就会占用越来越多的系统资源, 进而引起系统崩溃 ,所谓的“ 雪崩效应 ”也叫 服务雪崩 。
对于高流量的应用来说,单一的后端依赖可能会导致所有服务器上的所有资源都在几秒钟内饱和 比失败更糟糕的是,这些应用程序还可能导致服务之间的延迟增加,备份队列,线程和其他系统资源紧张,导致整个系统发生更多的级联故障。 这些都表示需要对故障和延迟进行隔离和管理,以便单个依赖关系的失败,不能取消整个应用程序或系统。
断路器Hystrix介绍
Hystrix是一个 用于处理分布式系统的延迟和容错 的开源库,在分布式系统里,许多依赖不可避免的会调用失败,比如超时、异常等问题 Hystrix能够保证在一个依赖出问题的情况下,不会导致整体服务失败,避免级联故障,以提高分布式系统的弹性。
断路器”本身是一种开关装置,当某个服务单元发生故障之后 通过断路器的故障监控(类似熔断保险丝),向调用方返回一个符合预期的、可处理的备选响应(FallBack),而不是长时间的等待或者抛出调用方无法处理的异常,这样就保证了服务调用方的线程不会被长时间、不必要地占用,从而避免了故障在分布式系统中的蔓延,乃至雪崩。
Hystrix功能包括:服务降级,服务熔断,服务限流,几近实时监控
服务熔断
- 熔断机制是应对雪崩效应的一种微服务链路保护机制。
- 当扇出链路的某个微服务不可用或者响应时间太长时,会进行服务的降级,进而熔断该节点微服务的调用,快速返回“错误”的响应信息。当检测到该节点微服务调用响应正常后恢复调用链路。
在Spring Cloud框架里熔断机制通过Hystrix实现。Hystrix会监控微服务间调用的状况,当失败的调用到一定阈值,缺省是5秒内20次调用失败就会启动熔断机制。熔断机制的注解是@HystrixCommand。
服务降级
服务降级服务降级的处理是在客户端完成的,与服务端没有关系。 整体资源快不够用了,忍痛将某些服务先关掉,待度过难关,再回来开启。
所谓 降级就是一般是从整体符合考虑,就是当某个服务熔断之后,服务器将不再被调用,此刻客户端可以自己准备一个本地的fallback回调,返回一个缺省值 这样做,虽然服务水平下降,但好歹可用, 比直接挂掉要强。
使用步骤
引入依赖
<!--hystrix依赖,主要是用 @HystrixCommand -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
**** 所有需要被监控的微服务引入如下依赖****
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
@HystrixCommand
核心配置
启用断路器
@HystrixProperty(name = "circuitBreaker.enabled", value = "true")
设置请求次数
@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10")
设置时间窗口期
@HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "10000")
设置失败率
@HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "60")
如上设置的值,如果在10秒内,失败率达到请求次数(10)的百分之60,也就是6次就会 打开断路器;否则断路器依然关闭
当断路器开启时,所有的请求都不会转发,而是直接调用fallback方法 ;在一段时间后(默认5秒),断路器处于半开状态,尝试将请求转发 如果得到正确的响应,则将断路器关闭,恢复正常调用 ;否则断路器状态再次打开,重新计时后再进入半开状态
@Component
public class PaymentService {
@HystrixCommand(fallbackMethod = "breakFallback", commandProperties = {
// 开启断路器
@HystrixProperty(name = "circuitBreaker.enabled", value = "true"),
// 请求次数
@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"),
// 时间窗口期
@HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "10000"),
// 失败率
@HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "60")
})
public String breakTest(Integer id) {
if (id < 0) {
throw new RuntimeException("ID 不能为负数");
}
return "正常访问: " + IdUtil.simpleUUID();
}
public String breakFallback(Integer id) {
return Thread.currentThread().getName() + "ID 不能为负数 熔断服务降级FallBack!" + id;
}
}
启动类加上注解
熔断降级示例
以两个服务端一个客户端为例,降级在客户端进行,熔断在服务端进行
客户端
@FeignClient(name = "server",value = "server",fallback = MessageServiceFallback.class)
public interface HelloFeign {
/**
* 正常调用
* @param id
* @return
*/
@GetMapping("/normal/{id}")
String normal(@PathVariable("id") int id);
}
FallBack配置类
@Component
public class MessageServiceFallback implements HelloFeign {
@Override
public String normal(int id) {
return "Error time out !!!";
}
}
配置文件
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 1500 # 超时时间
接口层
@RestController
public class HelloController {
@Resource
public HelloService helloService;
@GetMapping("/normal")
public void normal() {
for (int i = 0; i < 30; i++) {
System.out.println(helloService.normal(i));
}
}
}
服务端
接口层
@RestController
public class HelloController {
@Value("${server.port}")
private int port;
@Value("${spring.application.name}")
private String name;
@GetMapping("/normal/{id}")
//表示只对该接口生效
@HystrixCommand(fallbackMethod = "breakFallback",commandProperties = {
//开启熔断
@HystrixProperty(name="circuitBreaker.enabled",value = "true"),
//设置Hystrix的超时时间,默认1s
@HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value = "1000"),
//监控时间 默认5000 毫秒
@HystrixProperty(name="circuitBreaker.sleepWindowInMilliseconds",value = "10000"),
//失败次数。默认20次
@HystrixProperty(name="circuitBreaker.requestVolumeThreshold",value = "5"),
//失败率 默认50%
@HystrixProperty(name="circuitBreaker.errorThresholdPercentage",value = "50")
})
public String normal(@PathVariable("id") int id) {
if (id > 9 && id % 2 == 0) {
try {
sleep(1500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return id + " : 你调用的服务名称为: " + name + " ,端口为 : " + port;
}
public String breakFallback(int id) {
return id+": 端口 : "+ port+" 服务已熔断!!!";
}
}
配置文件
hystrix:
command:
default:
circuitBreaker:
errorThresholdPercentage: 50 # 触发熔断错误比例阈值,默认值50%
sleepWindowInMilliseconds: 10000 # 熔断后休眠时长,默认值5秒
requestVolumeThreshold: 10 # 熔断触发最小请求次数,默认值是20
execution:
isolation:
thread:
timeoutInMilliseconds: 2000 # 熔断超时设置,默认为1秒
最终效果
0 : 你调用的服务名称为: server ,端口为 : 8888
1 : 你调用的服务名称为: server ,端口为 : 7777
2 : 你调用的服务名称为: server ,端口为 : 8888
3 : 你调用的服务名称为: server ,端口为 : 7777
4 : 你调用的服务名称为: server ,端口为 : 8888
5 : 你调用的服务名称为: server ,端口为 : 7777
6 : 你调用的服务名称为: server ,端口为 : 8888
7 : 你调用的服务名称为: server ,端口为 : 7777
8 : 你调用的服务名称为: server ,端口为 : 8888
9 : 你调用的服务名称为: server ,端口为 : 7777
Error time out !!!
11 : 你调用的服务名称为: server ,端口为 : 8888
Error time out !!!
13 : 你调用的服务名称为: server ,端口为 : 7777
Error time out !!!
15 : 你调用的服务名称为: server ,端口为 : 8888
Error time out !!!
17 : 你调用的服务名称为: server ,端口为 : 7777
Error time out !!!
19 : 你调用的服务名称为: server ,端口为 : 8888
Error time out !!!
21 : 你调用的服务名称为: server ,端口为 : 7777
Error time out !!!
23: 端口 : 8888 服务已熔断!!!
24: 端口 : 7777 服务已熔断!!!
25: 端口 : 8888 服务已熔断!!!
26: 端口 : 7777 服务已熔断!!!
27: 端口 : 8888 服务已熔断!!!
28: 端口 : 7777 服务已熔断!!!
29: 端口 : 8888 服务已熔断!!!
Hystrix Dashboard
- Delay: 该参数用来控制服务器上轮询监控信息的延迟时间,默认为2000毫秒,可以通过配置该属性来降低客户端的网络和 CPU消耗。
- Title:该参数对应了头部标题Hystrix Stream之后的内容,默认会使用具体监控实例的URL,可以通过配置该信息来展示更合 适的标题。
- 监控查看:实心圆:共有两种含义。它通过颜色的变化代表了实例的健康程度,它的健康度从绿色<黄色<橙色<红色递减。
- 该实心圆除了颜色的变化之外,它的大小也会根据实例的请求流量发生变化,流量越大该实心圆就越大。所以通过该实心圆的展示 就可以在大量的实例中快速的发现故障实例和高压力实例。
Feign
声明式的服务调用Feign
Feign简介
是一个声明式的Web服务客户端,使得编写Web服务客户端变得非常容易。 只需要创建一个接口,然后在上面添加注解即可。
Feign的作用
Feign 旨在使编写Java Http客户端变得更容易 。前面在使用Ribbon & RestTemplate时,利用RestTemplate对http请求的封装处理,形成了一套模版化的调用方法。但是在实际开发中,由于对服务依赖的调用可能不止一处, 往往一个接口会被多处调用,所以通常都会针对每个微服务自行封装一些客户端类来包装这些依赖服务的调用。 所以, Feign在此基础上做了进一步封装,由他来帮助我们定义和实现依赖服务接口的定义 。在Feign的实现下,我们只需创建一个接口并使用注解的方式来配置它(以前是Dao接口上面标注Mapper注解,现在是一个微服务接口上面 标注一个Feign注解即可 ),即可完成对服务提供方的接口绑定,简化了使用Spring cloud Ribbon时,自动封装服务调用客户端的开发量。
引入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
@FeignClient
定义一个FeignClient客户端,其实就是定义个一个接口,加上@feignClient注解
@FeignClient(value = "CART")
public interface CartFeignClient {
@PostMapping("/cart/{productId}")
Long addCart(@PathVariable("productId")Long productId);
}
上面是最简单的feign client的使用,声明完为feign client后,其他spring管理的类,如service就可以直接注入使用了,例如
//这里直接注入feign client
@Autowired
private CartFeignClient cartFeignClient;
@PostMapping("/toCart/{productId}")
public ResponseEntity addCart(@PathVariable("productId") Long productId){
Long result = cartFeignClient.addCart(productId);
return ResponseEntity.ok(result);
}
启动类添加注解
Gateway
引入依赖
<!--网关-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
配置文件
# 服务名称
spring:
application:
name: gateway
# 开启 Gateway 服务注册中心服务发现
cloud:
gateway:
discovery:
locator:
enabled: true
routes:
- id: client
uri: lb://client
predicates:
- Path=/client/**
# Eureka Server 配置
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
# 配置Gateway日志等级,输出转发细节信息
logging:
level:
org.springframework.cloud.gateway: info
server:
port: 8080
启动后Eureka效果如图
通过8080端口我们即可访问其他模块的服务
我们在下图可以看到,gateway挑选了一个客户端服务进行调用
Zuul
Zuul路由网关
- Zuul包含了对 请求的路由和过滤 两个最主要的功能
- 其中 路由功能负责将外部请求转发到具体的微服务实例上 ,是实现外部访问统一入口的基础而过滤器功能则负责对请求的处理过程进行干预,是实现请求校验、服务聚合等功能的基础.
- Zuul和Eureka进行整合,将 Zuul自身注册为Eureka服务治理下的应用,同时从Eureka中获得其他微服务的消息 ,也即以后的访问微服务都是通过Zuul跳转后获得。
- Zuul服务 最终还是会注册进Eureka。Zuul功能:服务代理、路由、过滤三大功能
引入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
配置文件
server:
port: 9528
spring:
application:
name: cloud-zuul
eureka: #将zuul注册进服务注册中心
client:
service-url:
defaultZone: http://localhost:8761/eureka,http://localhost:8762/eureka,http://localhost:8763/eureka
register-with-eureka: true
fetch-registry: true
registry-fetch-interval-seconds: 10
instance:
instance-id: Zuul-9528 #修改在eureka注册中心status列显示的服务实例id,默认是主机名+服务名+端口
prefer-ip-address: true #设置为true,将鼠标悬停在注册中心status列的服务实例上,浏览器左下角显示ip和端口
zuul:
routes:
payment: #payment是自定义的名字,随便定义
serviceId: eureka-client #真实的服务名字
path: /eureka-client/** #配置访问的路径,路径中带有eureka-client 的请求会被路由到真实的服务。
# ignored-services: cloud-payment-service #不能通过服务名字进行访问的服务的名字
# prefix: /cloud-service #为所有访问路径再添加前缀
启动类加入注解
在启动类上添加注解 @EnableZuulProxy和@EnableEurekaClient ,将Zuul网关服务注册到Eureka,可以通过服务名称调用其他的服务
Spring Cloud Config
- 微服务意味着要将单体应用中的业务拆分成一个个自服务, 每个服务的粒度相对较小,因此系统中会出现大量的服务。 由于每个服务都 需要必要的配置 才能运行,所以一套 集中式的、动态的配置管理 设施是必不可少的。
- Spring Cloud Config为微服务架构中的微服务提供集中化的尾部配置支持,配置服务器为各个不同微服务应用的所有环境提供了一个中心化的外部配置。
- Spring Cloud Config分为服务端和客户端两部分。 服务端也称为分布式配置中心,它是一个独立的微服务应用,用来连接配置服务器并未客户端提供获取配置信息,加密/解密信息等访问接口。
- 客户端则是通过指定的配置中心来管理应用资源,以及与业务相关的配置内容,并在启动的时候从配置中心获取和加载配置信息 。配置服务器默认采用git来存储配置信息,这样就有助于对环境配置进行版本管理,并且可以通过git客户端工具来方便的管理和访问配置内容。
功能介绍
- 集中管理配置文件
- 不同环境不同配置,动态化的配置更新,分环境部署,比如dev/test/prod/beta/release
- 运行期间动态调整配置,不再需要在每个服务器的机器上编写配置文件 ,服务会向配置中心统一拉取配置自己的信息运行期间动态调整配置,不再需要在每个服务部署的机器上编写配置文件,服务会想配置中心统 一拉取配置自己的信息
- 当配置发生变动时, 服务不需要重启即可感知到配置的变化并应用新的配置
- 将配置信息以REST接口的形式暴露
引入依赖
<!-- spring cloud config 服务端包 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
架构分解
- 网关集群:数据的聚合、实现对接入客户端的身份认证、防报文重放与防数据篡改、功能调用的业务鉴权、响应数据的脱敏、流量与并发控制等
- 业务集群:一般情况下移动端访问和浏览器访问的网关需要隔离,防止业务耦合
- Local Cache:由于客户端访问业务可能需要调用多个服务聚合,所以本地缓存有效的降低了服务调用的频次,同时也提示了访问速度。本地缓存一般使用自动过期方式,业务场景中允许有一定的数据延时。
- 服务层:原子服务层,实现基础的增删改查功能,如果需要依赖其他服务需要在Service层主动调用
- Remote Cache:访问DB前置一层分布式缓存,减少DB交互次数,提升系统的TPS
- DAL:数据访问层,如果单表数据量过大则需要通过DAL层做数据的分库分表处理。
- MQ:消息队列用来解耦服务之间的依赖,异步调用可以通过MQ的方式来执行数据库主从:服务化过程中毕竟的阶段,用来提升系统的TPS
此处评论已关闭