服务拆分
服务拆分的注意事项
根据功能模块进行服务拆分,随着扩展可能会继续拆分
- 注意业务逻辑的单一职责,不要出现重复的业务逻辑实现。不同微服务,不要开发相同业务。
比如在订单模块中需要查询用户,应该跟用户模块进行通信获取,而不是直接在订单模块中访问数据库(即应该是 service 之间的互相调用,而不能够访问不该访问的 mapper)
- 微服务数据独立,不要访问其他微服务的数据库
- 微服务可以将自己的业务暴露为接口,供其他微服务调用(RESTful 接口)
- 不同微服务都应该有自己独立的数据库(物理上防止其他微服务访问自己的数据库)
服务间调用
原理:通过 HTTP 请求请求 RESTful 接口获取数据,与具体语言无关,只要知道对方的 url 和需要的参数即可获取,因此只需要知道 Java 代码中如何发起 HTTP 请求来获得相应数据
RestTemplate:Spring 提供的 HTTP 请求方式
/** |
Eureka 服务中心
服务提供者与服务消费者
- 服务提供者:一次业务中,被其他微服务调用的服务。(提供接口给其他微服务)
- 服务消费者:一次业务中,调用其他微服务的服务(调用其他微服务提供的接口)
服务A调用服务B,服务B调用服务C,服务B是什么角色?
相对的,相对A是服务提供者,相对C是服务消费者。(一个服务既可以是提供者也可以是消费者)
Eureka 注册中心
服务调用出现的问题
- ip和端口硬编码,地址变化和多实例都会导致硬编码失效和失去扩展性
- 如果有多个服务提供者,消费者如何选择
- 消费者如何得知服务提供者的健康状态
Eureka的作用
- eureka-server:注册中心
- eureka-client:各个微服务
- 每个微服务在启动时将自己注册到 eureka-server 上。某个服务消费者在需要调用其他微服务时,通过其他微服务来获取可用的微服务。(不用硬编码ip和端口)
- 与 eureka-server 通过心跳检测机制来持续注册,每30s发送一次心跳检测,如果超过时间还未发送,则会取消该 client 在 eureka-server 上的注册(感知服务状态)
- 服务消费者通过 eureka-server 获取需要的微服务的所有实例(byName,服务名称是很重要的),通过负载均衡选择服务来进行远程调用(负载均衡来选择提供者)
需要注意的是,在 eureka 中服务消费者是通过服务名称来获取对应的服务提供者的,因此
spring.application.name
是十分重要的,需要在 yaml 中明确定义且约定好服务的名称。
Eureka示例
- pom.xml 中导入对应的依赖
<dependency> |
- 启动类上加上
@EnableEurekaServer
注解 - application.yml 中编写 eureka-server 配置
server: |
服务注册
- pom.xml 导入配置
<dependency> |
- 启动类上加上
@EnableEurekaClient
注解 - application.yml 文件中添加
spring: |
服务拉取
- 通过服务名称替代ip + 端口
- 将 RestTemplate 添加
@LoadBalanced
来负载均衡
/** |