认识微服务
-
传统的单体架构:所有的模块集中在一个项目中开发,打成一个包部署。适合小型项目,比如学生管理系统
-
优点:
- 架构简单
- 部署成本低
-
缺点:
- 耦合度高
-
分布式架构:根据业务功能对系统进行拆分、每个业务模块独立开发、一个模块就是一个服务。适合大型互联网项目,比如京东、淘宝
-
优点:
- 降低耦合度
- 有利于服务升级拓展
-
缺点:
- 服务调用关系错综复杂
-
微服务是一种经过良好架构设计的分布式方案,微服务架构特征:
-
单一职责:拆分粒度小,每个服务对应的唯一的业务能力,避免重复开发
- 面向服务:对外暴露业务接口
- 自治:团队独立、技术独立、数据独立、部署独立
- 隔离性强:隔离、容错、降级,避免出现级联问题
-
微服务的技术对比
- 国内比较知名的就是SpringBoot和阿里巴巴的Dubbo
SpringBoot需要和Springcloud兼容,否则就会容易出现问题
Spring 官方对应版本地址: start.spring.io/actuator/in…
{
"git":**{
"branch":"c0755135ec24ea316f2e4452458e5e43babfdea6",
"commit":**{
"id":"c075513",
"time":"2023-05-09T15:05:09Z"
}
},
"build":**{
"version":"0.0.1-SNAPSHOT",
"artifact":"start-site",
"versions":**{
"spring-boot":"3.0.6",
"initializr":"0.20.0-SNAPSHOT"
},
"name":"start.spring.io website",
"time":"2023-05-09T17:05:04.891Z",
"group":"io.spring.start"
},
"bom-ranges":**{
"codecentric-spring-boot-admin":**{
"2.4.3":"Spring Boot >=2.3.0.M1 and <2.5.0-M1",
"2.5.6":"Spring Boot >=2.5.0.M1 and <2.6.0-M1",
"2.6.8":"Spring Boot >=2.6.0.M1 and <2.7.0-M1",
"2.7.4":"Spring Boot >=2.7.0.M1 and <3.0.0-M1",
"3.0.3":"Spring Boot >=3.0.0-M1 and <3.1.0-M1"
},
"solace-spring-boot":**{
"1.1.0":"Spring Boot >=2.3.0.M1 and <2.6.0-M1",
"1.2.2":"Spring Boot >=2.6.0.M1 and <3.0.0-M1"
},
"solace-spring-cloud":**{
"1.1.1":"Spring Boot >=2.3.0.M1 and <2.4.0-M1",
"2.1.0":"Spring Boot >=2.4.0.M1 and <2.6.0-M1",
"2.3.2":"Spring Boot >=2.6.0.M1 and <3.0.0-M1"
},
"spring-cloud":**{
"Hoxton.SR12":"Spring Boot >=2.2.0.RELEASE and <2.4.0.M1",
"2020.0.6":"Spring Boot >=2.4.0.M1 and <2.6.0-M1",
"2021.0.0-M1":"Spring Boot >=2.6.0-M1 and <2.6.0-M3",
"2021.0.0-M3":"Spring Boot >=2.6.0-M3 and <2.6.0-RC1",
"2021.0.0-RC1":"Spring Boot >=2.6.0-RC1 and <2.6.1",
"2021.0.7":"Spring Boot >=2.6.1 and <3.0.0-M1",
"2022.0.0-M1":"Spring Boot >=3.0.0-M1 and <3.0.0-M2",
"2022.0.0-M2":"Spring Boot >=3.0.0-M2 and <3.0.0-M3",
"2022.0.0-M3":"Spring Boot >=3.0.0-M3 and <3.0.0-M4",
"2022.0.0-M4":"Spring Boot >=3.0.0-M4 and <3.0.0-M5",
"2022.0.0-M5":"Spring Boot >=3.0.0-M5 and <3.0.0-RC1",
"2022.0.0-RC1":"Spring Boot >=3.0.0-RC1 and <3.0.0-RC2",
"2022.0.0-RC2":"Spring Boot >=3.0.0-RC2 and <3.0.0",
"2022.0.2":"Spring Boot >=3.0.0 and <3.1.0-M1"
},
"spring-cloud-azure":**{
"4.7.0":"Spring Boot >=2.5.0.M1 and <3.0.0-M1",
"5.1.0":"Spring Boot >=3.0.0-M1 and <3.1.0-M1"
},
"spring-cloud-gcp":**{
"2.0.11":"Spring Boot >=2.4.0-M1 and <2.6.0-M1",
"3.5.0":"Spring Boot >=2.6.0-M1 and <3.0.0-M1",
"4.3.0":"Spring Boot >=3.0.0-M1 and <3.1.0-M1"
},
"spring-cloud-services":**{
"2.3.0.RELEASE":"Spring Boot >=2.3.0.RELEASE and <2.4.0-M1",
"2.4.1":"Spring Boot >=2.4.0-M1 and <2.5.0-M1",
"3.3.0":"Spring Boot >=2.5.0-M1 and <2.6.0-M1",
"3.4.0":"Spring Boot >=2.6.0-M1 and <2.7.0-M1",
"3.5.0":"Spring Boot >=2.7.0-M1 and <3.0.0-M1",
"4.0.0":"Spring Boot >=3.0.0 and <3.1.0-M1"
},
"spring-shell":**{
"2.1.9":"Spring Boot >=2.7.0 and <3.0.0-M1",
"3.0.3":"Spring Boot >=3.0.0 and <3.1.0-M1"
},
"vaadin":**{
"14.9.6":"Spring Boot >=2.1.0.RELEASE and <2.6.0-M1",
"23.2.15":"Spring Boot >=2.6.0-M1 and <2.7.0-M1",
"23.3.11":"Spring Boot >=2.7.0-M1 and <3.0.0-M1",
"24.0.5":"Spring Boot >=3.0.0-M1 and <3.1.0-M1"
},
"wavefront":**{
"2.0.2":"Spring Boot >=2.1.0.RELEASE and <2.4.0-M1",
"2.1.1":"Spring Boot >=2.4.0-M1 and <2.5.0-M1",
"2.2.2":"Spring Boot >=2.5.0-M1 and <2.7.0-M1",
"2.3.4":"Spring Boot >=2.7.0-M1 and <3.0.0-M1",
"3.0.1":"Spring Boot >=3.0.0-M1 and <3.1.0-M1"
}
},
"dependency-ranges":**{
"okta":**{
"1.4.0":"Spring Boot >=2.2.0.RELEASE and <2.4.0-M1",
"1.5.1":"Spring Boot >=2.4.0-M1 and <2.4.1",
"2.0.1":"Spring Boot >=2.4.1 and <2.5.0-M1",
"2.1.6":"Spring Boot >=2.5.0-M1 and <3.0.0-M1",
"3.0.3":"Spring Boot >=3.0.0-M1 and <3.1.0-M1"
},
"mybatis":**{
"2.1.4":"Spring Boot >=2.1.0.RELEASE and <2.5.0-M1",
"2.2.2":"Spring Boot >=2.5.0-M1 and <2.7.0-M1",
"2.3.0":"Spring Boot >=2.7.0-M1 and <3.0.0-M1",
"3.0.0":"Spring Boot >=3.0.0-M1"
},
"pulsar":**{
"0.2.0":"Spring Boot >=3.0.0 and <3.1.0-M1"
},
"pulsar-reactive":**{
"0.2.0":"Spring Boot >=3.0.0 and <3.1.0-M1"
},
"camel":**{
"3.5.0":"Spring Boot >=2.3.0.M1 and <2.4.0-M1",
"3.10.0":"Spring Boot >=2.4.0.M1 and <2.5.0-M1",
"3.13.0":"Spring Boot >=2.5.0.M1 and <2.6.0-M1",
"3.17.0":"Spring Boot >=2.6.0.M1 and <2.7.0-M1",
"3.20.4":"Spring Boot >=2.7.0.M1 and <3.0.0-M1",
"4.0.0-M3":"Spring Boot >=3.0.0-M1 and <3.1.0-M1"
},
"picocli":**{
"4.7.0":"Spring Boot >=2.5.0.RELEASE and <3.1.0-M1"
},
"open-service-broker":**{
"3.2.0":"Spring Boot >=2.3.0.M1 and <2.4.0-M1",
"3.3.1":"Spring Boot >=2.4.0-M1 and <2.5.0-M1",
"3.4.1":"Spring Boot >=2.5.0-M1 and <2.6.0-M1",
"3.5.0":"Spring Boot >=2.6.0-M1 and <2.7.0-M1"
}
}
}
示例
- 导入demo项目,开启两个服务
- 在浏览器中输入http://localhost:8080/order/101 和 http://localhost:8081/user/3 拿到数据 可以看到订单只能查询订单信息,不能查到用户信息,所以在订单模块中进行修改,在根据订单id查询的同时返回用户信息。可以基于RestTemplate发起http请求实现远程调用,在调用过程中,被其他微服务调用的服务叫做服务提供者,调用其他微服务的服务叫做服务消费者。具体根据业务判断。抛开业务不谈,一个服务既可以是提供者(暴露接口),也可以是消费者(调用服务)。
- 在配置类中注册RestTemplate
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
- 修改对应的Service方法
@Service
public class OrderService {
@Autowired
private OrderMapper orderMapper;
@Autowired
private RestTemplate restTemplate;
public Order queryOrderById(Long orderId) {
// 1.查询订单
Order order = orderMapper.findById(orderId);
//2. 利用RestTemplate发起http请求,根据用户Id查询用户
//get请求就是getForObject,post请求postForObject
//参数: url请求的连接,ResponseType请求映射的对象
String url = "http://localhost:8081/user/" + order.getUserId();
User user = restTemplate.getForObject(url, User.class);
//封装对象
order.setUser(user);
// 4.返回
return order;
}
}
eureka
通过 Eureka 服务注册中心,我们可以将所有的微服务注册到 Eureka 服务器中,使得每一个微服务都可以互相发现并调用。同时 Eureka 还支持服务剔除机制,如果一个微服务出现故障或停止运行,Eureka 服务注册中心会自动将其从注册表中剔除,其他微服务不会再去请求该服务。
此外,Eureka 还提供了负载均衡的能力,比如,当请求到达 Eureka 服务中心时,Eureka 会对客户端的请求进行负载均衡,将请求分配给符合条件的微服务实例。
搭建EuekaServer
- 首先创建项目,引入依赖
<!--eureka服务端-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
- 创建主函数,开启注解
@SpringBootApplication
@EnableEurekaServer
public class EurekaApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaApplication.class,args);
}
}
- 在application.yml中配置eureka地址
server:
port: 10086 #服务端口
spring:
application:
name: eurekaserver # eureka的服务名称
eureka:
client:
service-url: # eureka的地址信息
defaultZone: http://本地地址/eureka
Eueka注册中心
- 在user-service项目中引入依赖
<!--eureka服务端-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
- 在application.yml中进行配置
spring:
application:
name: userserver # eureka的服务名称
eureka:
client:
service-url: # eureka的地址信息
defaultZone: http://本地地址/eureka
- 修改OrederService
public Order queryOrderById(Long orderId) {
// 1.查询订单
Order order = orderMapper.findById(orderId);
//2. 利用RestTemplate发起http请求,根据用户Id查询用户
//get请求就是getForObject,post请求postForObject
//参数: url请求的连接,ResponseType请求映射的对象
String url = "http://userservice/user/" + order.getUserId();
User user = restTemplate.getForObject(url, User.class);
//封装对象
order.setUser(user);
// 4.返回
return order;
}