在B站学习的springcloud的学习记录,第二天,最难不过坚持。
配置和环境:idea2022 jdk8 mysql8.0
本文章只用于学习和分享,欢迎大家的建议,讨论和指点。
目录
创建一个eureka注册中心
继续是跟着杨哥五步走:建model 改pom 写yml 主启动 写业务
建model
添加依赖
<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/maven-v4_0_0.xsd">
<parent>
<artifactId>cloud2023</artifactId>
<groupId>com.liangliang</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>cloud-eureka-server7001</artifactId>
<packaging>war</packaging>
<name>cloud-eureka-server7001 Maven Webapp</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<!--eureka服务器-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<build>
<finalName>cloud-eureka-server7001</finalName>
</build>
</project>
写application.yml文件
server:
port: 7001 #端口号
spring:
application:
name: eurekaservice #服务名称
eureka:
client:
service-url: #eureka的地址信息
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ #eureka集群的信息
register-with-eureka: false
fetch-registry: false
写主启动类
比平时的启动类添加多一个注解
@SpringBootApplication
@EnableEurekaServer
public class EurekaMain7001 {
public static void main(String[] args) {
SpringApplication.run(EurekaMain7001.class,args);
}
}
@EnableEureaServer将该model创建成一个eureka服务注册中心
运行该程序
将服务注册到eureka中
将之前创建的两个微服务注册进eureka注册中心中。
按照步骤改pom->写yml->主启动类的步骤,将两个服务添加到eureka服务注册中心中
在支付模块和消费者模块的pom中添加依赖eureka-client的依赖
之前的两个微服务可以看着里支付模块的微服务,消费者模块的微服务
在他们的基础上改pom,添加依赖
<!-- eureka-client 依赖jar包-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
在yml文件中添加配置
eureka:
client:
register-with-eureka: true #表示自己注册到eurekaServer中默认是true
fetch-registry: true
service-url:
defaultZone: http://localhost:7001/eureka
在各自的主启动类中添加注解@EnableEurekaClient
@EnableEureakaClient将该微服务注册进eureka中
再重新的启动微服务
这样两个服务就会注册到eureka服务注册中心里了
Eureka 的自我保护机制理念
默认情况下,如果eurekaserver在一定时间内没有接受到某个微服务实例的心跳反应,就会注销这个实例(默认是90秒),
如果在短时间内丢失了大量的服务实例心跳,这是eurekaserver会开启知我保护机制,不会剔除该服务
某一时刻某一服务不可用了,eureka不会立刻清理掉,依旧会对改微服务的信息进行保存。
OpenFeign服务调用
OpenFeign 是一个声明式webService客户端,让编写web服务更加的容易,只需要创建一个接口,然后在接口上添加注解对他进行配置就行了,对服务提供方的接口进行绑定。
也是可以用于负载均衡的作用,与ribbon的功能相似。
先是通过注解注入,微服务调用接口+@feginClient
Openfeign负载均衡
经典五步走
建model
改pom
新添加openfeign的依赖和eureka-client注册服务
调用自己的api包,节省写实体类代码
<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/maven-v4_0_0.xsd">
<parent>
<artifactId>cloud2023</artifactId>
<groupId>com.liangliang</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>cloud-consumer-feign-order81</artifactId>
<packaging>war</packaging>
<name>cloud-consumer-feign-order81 Maven Webapp</name>
<url>http://maven.apache.org</url>
<dependencies>
<!-- openfeign-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!-- eureka-client-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!-- 自定义的api调用包-->
<dependency>
<groupId>com.liangliang</groupId>
<artifactId>cloud-api-commons</artifactId>
<version>${project.version}</version>
</dependency>
<!-- web-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--以上两个一定携带出现 包括了图形化、图标等-->
<!-- 一些通用配置-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<finalName>cloud-consumer-feign-order81</finalName>
</build>
</project>
写yml,将服务注册到eureka服务中心中
server:
port: 81
eureka:
client:
register-with-eureka: false #表示自己注册到eurekaServer中默认是true
service-url:
defaultZone: http://localhost:7001/eureka #单机版
主启动 ---添加注解@EnableFeignClients
@SpringBootApplication
@EnableFeignClients
public class OrderFeignMain81 {
public static void main(String[] args) {
SpringApplication.run(OrderFeignMain81.class,args);
}
}
写业务服务类
使用Openfeign 只需要创建一个接口进行配置,创建一个Server包,创建openfeignService类
@Component
@FeignClient(value = "CLOUD-PAYMENT-SERVICE")
public interface PaymentFeignService
{
// CommonResult<Payment> getPaymentById(@Param("id")long id);
// 通过这些找到需要的微服务里面暴露出来的方法
@GetMapping(value = "/payment/get/{id}")
public CommonResult<Payment> getPaymentById(@PathVariable("id") Long id);
}
然后在编写控制类,并调用openfeignservice中的方法
@RestController
@Slf4j
public class OrderFeignController {
@Autowired
private PaymentFeignService paymentFeignService;
@GetMapping(value = "/consumer/payment/get/{id}")
public CommonResult<Payment> getPaymentById(@PathVariable("id")Long id){
return paymentFeignService.getPaymentById(id);
}
}
测试结果:
自动的实现了负载均衡,每次刷新serverport端口都在8001和8002 中轮询
OpenFeign的超时控制
在模拟支付模块中添加代码,异常处理线程暂停。
故意在支付模块的控制类中暂停几秒的线程,模仿业务在处理时异常或者需要暂停几秒进行处理业务
在支付模块(8001端口)的控制类中自定义异常处理,使线程处理时暂停三秒。
@GetMapping(value = "/payment/lb")
public String getPaymentLB(){
return serverPort;
}
@GetMapping(value = "/payment/feign/timeout")
public String paymentFeignTimeOut(){
// 暂停几秒钟线程,模拟异常或者业务线程暂停三秒
try {
TimeUnit.SECONDS.sleep(3);
}catch (InterruptedException e) {
e.printStackTrace();
}
return serverPort;
}
然后在消费者模块(81端口)的consumer-Feign-order81的model的service接口中添加代码
@GetMapping(value = "/payment/feign/timeout")
public String paymentFeignTimeOut();
在控制类中添加调用的代码
@GetMapping(value = "/consumer/payment/feign/timeout")
public String paymentFeignTimeOut(){
// openfeign-ribbon 客户端一般默认等待一秒钟,现在人为地延长业务三秒钟
return paymentFeignService.paymentFeignTimeOut();
}
重新启动项目,我们可用看到在orderFeign中的测试显示超时。
Feign客户端默认只等待一秒钟,但是服务端处理需要超过一秒,导致feign客户端不想等待,直接返回报错,为了避免这样的情况,我们需要设置feign客户端的超时控制。
我们可以在yml文件中开启配置
ribbon:
ReadTimeout: 5000 #指建立连接的时间
ConnectTimeout: 5000 #指建立连接时间后服务器读取可用资源所用的时间
重新刷新页面
可以发现在8001端口模拟超时异常的作用下,因为yml的超时控制配置,81端口也能得到响应。
日志增强
Feign提供了日志打印功能,可用通过配置来调整日志级别,从而了解feign中http请求的细节,说白了就是对feign接口的调用情况进行监控了输出。
在feign这个model中创建一个config包
编写日志监控和记录的代码
**
* 开启一个详细的日记监控和记录
*/
@Configuration
public class FeignConfig {
@Bean
Logger.Level feignLongLevel(){
return Logger.Level.FULL;
}
}
在yml文件中添加配置
logging:
level:
#feign日志以什么级别监控哪个接口
com.liangliang.springcloud.service.PaymentFeignService: debug