认识微服务
1.服务架构也从单体架构逐渐演变为现在流行的微服务架构。这些架构之间有怎样的差别呢?优缺点?
单体架构:整个项目仅仅只有一个模块可以单独运行和部署。

优点:架构简单,易于部署
缺点:耦合度高,维护困难,升级困难(牵一发而动全身)
分布式架构:对项目进行拆分,拆分成多个模块,每个模块可以单独运行和部署。

优点:耦合度低,便于服务的扩展(某个服务访问压力大,可以只针对该服务搭建集群,其他服务不用动)。
缺点:服务调用关系错综复杂
分布式架构面临的问题(列举)
1.部署复杂。
2.如何远程调用。
3.前后端交五比较复杂。
小知识点:
将可以单独运行和部署的模块称之为=====>服务
服务之间可以进行通信(Http协议),服务之间的通信过程称之为=====>远程调用
微服务架构:就是分布式系统架构,对分布式系统架构提出一些明确目标

微服务的架构特征:
-
单一职责:微服务拆分粒度更小,每一个服务都对应唯一的业务能力,做到单一职责
-
自治:团队独立、技术独立、数据独立,独立部署和交付
-
面向服务:服务提供统一标准的接口,与语言和技术无关
-
隔离性强:服务调用做好隔离、容错、降级,避免出现级联问题
SpringCloud
SpringCloud是目前国内使用最广泛的微服务框架。
SpringCloud集成了各种微服务功能组件,并基于SpringBoot实现了这些组件的自动装配,从而提供了良好的开箱即用体验。
Springcloud: 提供了很多组件,可以解决微服务架构中各种问题。
注册中心: nacos,eureka,cosule
远程调用: dubbo feign
网关: zuul springcloudgateway
配置中心:springcloud config nacos
服务保护:sentinel Hystrix
数据准备:
项目结构(分模块开发):

数据库表(订单表,用户表):


订单服务,用户服务数据:
订单服务:pojo对象(order,user)
public class Order {
private Long id;
private Long price;
private String name;
private Integer num;
private Long userId;
private User user;
}
public class User {
private Long id;
private String username;
private String address;
}
订单服务:application.yml配置文件
订单服务:pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!--mybatis-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
用户服务:pojo对象(order,user)
public class User {
private Long id;
private String username;
private String address;
}
订单服务:application.yml配置文件
用户服务:pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!--mybatis-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
订单服务(通过id查询订单信息)
@RestController
@RequestMapping("/order")
public class OrderController {
@Autowired
private OrderService orderService;
@GetMapping("/{orderId}")
public Order getById(@PathVariable("orderId") Long id) {
Order order = orderService.getById(id);
return order;
}
}

用户服务(通过id查询用户信息)
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/{id}")
public User getUserById(@PathVariable Long id) {
User user = userService.getUserById(id);
return user;
}
}

远程调用
1.远程调用的本质?
在一个服务中向另外一个服务的controller方法发送http请求,获取响应结果
2.Java中发送HTTP请求使用RestTemplate(RestTemplate 是由 Spring 提供的一个 HTTP 请求工具。),RestTemplate使用流程?
2.1.将RestTemplate交由sprinq管理
2.2.注入RestTemplate
2.3.调用xxxForobject (),可以将响应ison转化为指定类型对象

order_service服务的业务层代码

Eureka(简化RestTemplate中URL的硬编码)
Spring Cloud 封装了 Netflix 公司开发的 Eureka 模块来实现服务注册和发现。Eureka 采用了 C-S 的设计架构。Eureka Server 作为服务注册功能的服务器,它是服务注册中心。而系统中的其他微服务,使用 Eureka 的客户端连接到 Eureka Server,并维持心跳连接。这样系统的维护人员就可以通过 Eureka Server 来监控系统中各个微服务是否正常运行。Spring Cloud 的一些其他模块(比如Zuul)就可以通过 Eureka Server 来发现系统中的其他微服务,并执行相关的逻辑。
Eureka由两个组件组成:Eureka服务器和Eureka客户端。Eureka服务器用作服务注册服务器。Eureka客户端是一个java客户端,用来简化与服务器的交互、作为轮询负载均衡器,并提供服务的故障切换支持。Netflix在其生产环境中使用的是另外的客户端,它提供基于流量、资源利用率以及出错状态的加权负载均衡。

名词解释:
服务注册:所有服务启动后,将自己的地址服务到注册中心。
服务发现:服务消费方,根据提供方名称,从注册中心获取提供方的地址列表。
心跳检测:每隔一段时间(默认30秒)向eureka-server发起请求,报告自己状态,称为心跳。当超过一定时间没有发送心跳时,eureka-server会认为微服务实例故障,将该实例从服务列表中剔除
eurke-server: eureka注册中心
eurke-client:微服务
Eureka的使用
1.搭建注册中心
1.1.创建eureka-server服务(这必须是一个独立的微服务 ,独立模块)
1.2.引入eureka依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
1.3.编写启动类
@SpringBootApplication
@EnableEurekaServer
public class EurekaApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaApplication.class,args);
}
}
1.4.编写配置文件
server:
port: 8090
spring:
application:
name: eureka-server
eureka:
client:
service-url:
#配置erueka注册中心地址
defaultZone: http://127.0.0.1:8090/eureka
1.5.启动eureka注册中心服务。
访问eureka注册中心管理控制台测试
http://ip:eureka注册中心端口
2.服务注册
2.1.引入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
2.2.配置文件
spring:
application:
name: userservice
eureka:
client:
service-url:
defaultZone: http://ip:端口号/eureka
2.3.可以搭载集群环境(可选)
3.服务发现
3.1.引入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
3.2.配置文件
spring:
application:
name: userservice
eureka:
client:
service-url:
defaultZone: http://ip:端口号/eureka
3.3.服务拉取和负载均衡
给RestTemplate这个Bean添加一个@LoadBalanced注解:
@Configuration
public class RestTemplateConfig {
@Bean
@LoadBalanced //开启负载均衡
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
3.4.修改访问的url路径,用服务名代替ip、端口:
@Service
public class OrderServiceImpl implements OrderService {
@Autowired
private OrderMapper orderMapper;
@Autowired
public RestTemplate restTemplate;
@Override
public Order getById(Long id) {
//根据用户id查询用户对象
Order order = orderMapper.getById(id);
Long userId = order.getUserId();
//向user_service服务发送http请求
String url = "http://userservice/user/"+userId;
//参数:指定访问路径,返回类型
User user = restTemplate.getForObject(url, User.class);
//将用户对象封装order对象
order.setUser(user);
return order;
}
}