狂神教学
https://www.bilibili.com/video/BV1jJ411S7xr?p=4
狂神推荐的网站(springcloud 中文手册)
https://www.springcloud.cc/spring-cloud-dalston.html
maven仓库
https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-dependencies/Greenwich.SR1
springboot与springcloud 版本兼容
Eureka模块
maven配置
我是直接用这个 上面自己配的 启动不了
ide创建 springboot + eureka
https://blog.csdn.net/weixin_46032603/article/details/108774805
配置文件 application.yml
server: port: 7001
#Eureka配置
eureka:
server:
# 关闭Eureka自我保护机制
enable-self-preservation: true
instance:
hostname: localhost #Eureka配置服务端的实例名称
client:
register-with-eureka: false #表示是否向eureka注册中心注册自己
fetch-registry: false #如果为false, 则表示自己为注册中心
service-url: #监控页面 注册地址 给提供服务的端配置的
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
SpringbootEurakaApplication 启动类文件
package com; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; @SpringBootApplication @EnableEurekaServer //服务端的启动类,可以接受别人注册进来 public class SpringbootEurakaApplication { public static void main(String[] args) { SpringApplication.run(SpringbootEurakaApplication.class, args); } }
pom.xml
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>springboot_euraka</artifactId> <version>0.0.1-SNAPSHOT</version> <name>springboot_euraka</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <spring-boot.version>2.3.7.RELEASE</spring-boot.version> <spring-cloud.version>Hoxton.SR9</spring-cloud.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </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> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>${spring-boot.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.1</version> <configuration> <source>1.8</source> <target>1.8</target> <encoding>UTF-8</encoding> </configuration> </plugin> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>2.3.7.RELEASE</version> <configuration> <mainClass>com.SpringbootEurakaApplication</mainClass> </configuration> <executions> <execution> <id>repackage</id> <goals> <goal>repackage</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </project>
提供服务的项目
application.yml 配置文件
#spring的配置
spring:
application:
name: FW01
# 应用服务 WEB 访问端口
server:
port: 8081
#Eureka配置,服务注册到那里
eureka:
client:
service-url: #监控页面 注册地址
defaultZone: http://localhost:7001/eureka/
instance:
instance-id: FW01-w8081 #修改eureka上的默认描述信息
#点击服务对应描述信息跳转到/actuator/info地址 配置你们展示的信息
info:
app.name: lucax-FW01
company.name: lucax.com
Fw01Application 启动文件
package com; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; @SpringBootApplication @EnableEurekaClient //在服务启动后自动注册到 Eureka中
@EnableDiscoveryClient //服务发现,加上这个在查看eurka上有那些服务时 也会返回自己
public class Fw01Application { public static void main(String[] args) { SpringApplication.run(Fw01Application.class, args); } }
pom文件
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>FW01</artifactId> <version>0.0.1-SNAPSHOT</version> <name>FW01</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <spring-boot.version>2.3.7.RELEASE</spring-boot.version> <spring-cloud.version>Hoxton.SR9</spring-cloud.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <!-- http://192.168.108.235:8081/actuator/info ,点eureka里自己的服务 展示信息--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </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> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>${spring-boot.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.1</version> <configuration> <source>1.8</source> <target>1.8</target> <encoding>UTF-8</encoding> </configuration> </plugin> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>2.3.7.RELEASE</version> <configuration> <mainClass>com.Fw01Application</mainClass> </configuration> <executions> <execution> <id>repackage</id> <goals> <goal>repackage</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </project>
eureka字段展示配置(提供服务端)
这个在pom文件要引入
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
鼠标放上面展示ip
instance:
instance-id: FW01-w8083-hystrix #修改eureka上的默认描述信息
prefer-ip-address: true #展示ip 我是加不加都展示 神奇
------获取注册在eureka上面的服务---注意在 Fw01Application 启动文件 加上注解 @EnableDiscoveryClient 意思就是 查询注册在上面的服务 不过滤自己
contorl01
package com.contorl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.client.discovery.DiscoveryClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import java.util.List; @RestController public class contorl01 { // 获取一些配置的信息,得到具体的微服务! @Autowired private DiscoveryClient client; @GetMapping("/man") public String checkMan() { return "获取人类"; } @GetMapping("/getServer") public Object discovery(){ // 获取微服务的清单 List<String> services=client.getServices(); System.out.println("discovery=>services"+services); // 得到一个具体的微服务信息,通过具体的微服务id,applicationName; List<ServiceInstance> instances = client.getInstances("FW01"); for (ServiceInstance instance:instances){ System.out.println( instance.getHost()+"\t"+ instance.getPort()+"\t"+ instance.getUri()+"\t"+ instance.getServiceId() ); } return this.client; } }
终端打印出
discovery=>services[fw01]
192.168.108.235 8081 http://192.168.108.235:8081 FW01
euraka集群
集群设置:
和上面Eureka模块配置的一样的,就在配置文件里面配置有点不一样,配置其他几个euraka配置的地址即可
application.yml
server: port: 7003 #Eureka配置 eureka: server: # 关闭Eureka自我保护机制 enable-self-preservation: true instance: hostname: localhost #Eureka配置服务端的实例名称 client: register-with-eureka: false #表示是否向eureka注册中心注册自己 fetch-registry: false #如果为false, 则表示自己为注册中心 service-url: (#监控页面 注册地址--写上其他几个euraka配置的注册地址即可) defaultZone: http://127.0.0.1:7001/eureka/,http://127.0.0.1:7002/eureka/
服务提供端:
application.yml
#Eureka配置,服务注册到那里 eureka: client: service-url: #监控页面 注册地址---写euraka配置的注册地址 defaultZone: http://127.0.0.1:7001/eureka/,http://127.0.0.1:7003/eureka/
(客户端、消费端)负载均衡--ribbon--调用服务--要搭配第三方请求
实线就是ribbon做的事情
使用服务端(消费者)
maven依赖
https://mvnrepository.com/search?q=ribbon
Restemconnfig。 ---------这里用了 restTemplate 库 见 : https://www.cnblogs.com/kaibindirver/p/15398815.html
package com.config; 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; @Configuration public class Restemconnfig { @Bean @LoadBalanced //配置负载均衡实现---Ribbon public RestTemplate restTemplate(){ return new RestTemplate(); } }
RequestUrl
package com.control; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.RestTemplate; @Slf4j @RestController public class RequestUrl { private final String url = "http://FW01"; //这里是服务端在euraka上注册的 应用名称 @Autowired private RestTemplate restTemplate; @GetMapping("/XF") public String resQuest() { ResponseEntity<String> responseEntity = restTemplate.getForEntity(url+"/man", String.class); log.info("响应: " + responseEntity); String body = responseEntity.getBody(); log.info(String.valueOf(body)); return "请求成功"; } }
XfApplication
package com; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; //Ribbon 和 Eureka 整合以后,客户端可以直接调用,不用关心ip地址和端口号 @SpringBootApplication @EnableEurekaServer //服务端的启动类,可以接受别人注册进来 public class XfApplication { public static void main(String[] args) { SpringApplication.run(XfApplication.class, args); } }
application.yml
#spring的配置 spring: application: name: XF # 应用服务 WEB 访问端口 server: port: 8080 #Eureka配置,服务注册到那里 eureka: client: register-with-eureka: false #表示不向eureka注册中心注册自己 service-url: #监控页面 注册地址 defaultZone: http://127.0.0.1:7001/eureka/,http://127.0.0.1:7003/eureka/
pom
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>XF</artifactId> <version>0.0.1-SNAPSHOT</version> <name>XF</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <spring-boot.version>2.3.7.RELEASE</spring-boot.version> <spring-cloud.version>Hoxton.SR9</spring-cloud.version> </properties> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-ribbon</artifactId> <version>1.4.7.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </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> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>${spring-boot.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.1</version> <configuration> <source>1.8</source> <target>1.8</target> <encoding>UTF-8</encoding> </configuration> </plugin> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>2.3.7.RELEASE</version> <configuration> <mainClass>com.XfApplication</mainClass> </configuration> <executions> <execution> <id>repackage</id> <goals> <goal>repackage</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </project>
上面是他会去找可用的注册中心中拿服务提供者
自定义ribbon的负载均衡见下面的教程
https://www.bilibili.com/video/BV1jJ411S7xr?p=12
如果是选择内置的,则修改Restemconnfig 文件即可
package com.config; import com.netflix.loadbalancer.IRule; import com.netflix.loadbalancer.RandomRule; 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; @Configuration public class Restemconnfig { @Bean @LoadBalanced //配置负载均衡实现---Ribbon public RestTemplate restTemplate(){ return new RestTemplate(); } // 配置负载均衡实现 RwatTemplate // IRule接口下面的方法有 // RoundRobbinRule 轮询 (不写默认是这个) // RanndomRule 随机 // AvailablityFilteringRule 会先过滤 跳闸 访问故障的服务~ 对剩下的进行轮询 // RetryRule 会先按照轮询获取服务,如果服务获取失败,则会在指定时间内进行 重试 @Bean public IRule myRule(){ return new RandomRule(); } }
(客户端、消费端) feign调用服务端---直接调不需要第三方请求
一般是剥离api为一个mode项目,因为别人项目调用时 就给他api的maven包
自己实践,为了方便我api没有独立出去
RequestUrl
package com.control; import com.server.DeptClict; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class RequestUrl { @Autowired private DeptClict service = null; //调feign 链接服务提供端 @GetMapping("/XF") public String resQuest() { return this.service.resQuest(); } }
DeptClict
package com.server; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.stereotype.Component; import org.springframework.web.bind.annotation.GetMapping; @Component @FeignClient(value="FW01") public interface DeptClict { @GetMapping("/man") //调用 FW01 服务提供端的 接口 就上面 提供服务的项目 contorl里面的接口 public String resQuest(); }
注意!!!!!!:
假如调用的接口是要接受参数的,要用正规的写法 指定接受的值
public String resQuest(@PathVariable("id") String id);
FeignApplication
package com; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; import org.springframework.cloud.openfeign.EnableFeignClients; import org.springframework.context.annotation.ComponentScan; //Ribbon 和 Eureka 整合以后,客户端可以直接调用,不用关心ip地址和端口号 @SpringBootApplication @EnableEurekaServer //服务端的启动类,可以接受别人注册进来 @EnableFeignClients(basePackages = {"com"}) 让他扫描这个包下的文件 feign的注解就会生效 //@ComponentScan("com") 这个教程里面说要加 ,但是我没加也成功,貌似是有啥自定义的才要加这个 class FeignApplication { public static void main(String[] args) { SpringApplication.run(FeignApplication.class, args); } }
application.yml
#spring的配置 spring: application: name: XF # 应用服务 WEB 访问端口 server: port: 8181 #Eureka配置,服务注册到那里 eureka: client: register-with-eureka: false #表示不向eureka注册中心注册自己 service-url: #监控页面 注册地址 defaultZone: http://127.0.0.1:7001/eureka/,http://127.0.0.1:7003/eureka/
pom
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>feign</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>XF</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<spring-boot.version>2.3.7.RELEASE</spring-boot.version>
<spring-cloud.version>Hoxton.SR9</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
<version>1.4.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</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>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.3.7.RELEASE</version>
<configuration>
<mainClass>com.XfApplication</mainClass>
</configuration>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
eureka 自我保护机制的配置:
https://www.cnblogs.com/zjfjava/p/12153130.html
hystrix 短路器
服务熔断演示-------方法出错定向另一个方法 (在服务端做)
contorl01
package com.contorl; import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cloud.client.discovery.DiscoveryClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController; import java.sql.SQLOutput; import java.util.List; @Slf4j @RestController public class contorl01 { // 获取一些配置的信息,得到具体的微服务! @Autowired private DiscoveryClient client; @GetMapping("/man/{id}") @HystrixCommand(fallbackMethod="HystrixcheckMan") //这个方法有出错就执行备用的方法 HystrixcheckMan public String checkMan(@PathVariable() String id) { if (id.equals("1")){ log.error("id不能为空"); throw new RuntimeException("id不能为空"); } return "获取人类Hystrix服务"+id; } public String HystrixcheckMan(@PathVariable() String id) { return "获取人类Hystrix服务调用失败备用方法"+id; } }
Fw03HystrixApplication
package com; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; @SpringBootApplication @EnableEurekaClient //在服务启动后自动注册到 Eureka中 @EnableDiscoveryClient //服务发现,加上这个在查看eurka上有那些服务时 也会返回自己 //添加对熔断的支持 @EnableCircuitBreaker public class Fw03HystrixApplication { public static void main(String[] args) { SpringApplication.run(Fw03HystrixApplication.class, args); } }
application.yml
#spring的配置 spring: application: name: FW01 # 应用服务 WEB 访问端口 server: port: 8083 #Eureka配置,服务注册到那里 eureka: client: service-url: #监控页面 注册地址 defaultZone: http://127.0.0.1:7001/eureka/,http://127.0.0.1:7003/eureka/ instance: instance-id: FW01-w8083-hystrix #修改eureka上的默认描述信息 #点击服务对应描述信息跳转到/actuator/info地址 配置你们展示的信息 info: app.name: lucax-FW02 company.name: lucax.com
pom
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>FW03-Hystrix</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>FW03-Hystrix</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<spring-boot.version>2.3.7.RELEASE</spring-boot.version>
<spring-cloud.version>Hoxton.SR9</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
<version>1.4.6.RELEASE</version>
</dependency>
<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>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!-- http://192.168.108.235:8081/actuator/info ,点eureka里自己的服务 展示信息-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</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>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.3.7.RELEASE</version>
<configuration>
<mainClass>com.Fw01Application</mainClass>
</configuration>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
(客户端做、消费方 )服务降级--就是请求某个类里面的api的时候给他转到另外一个类返回特定的内容
比方3个服务,现在一个服务要大量用,就可以先关闭其他服务的api
具体例子见 : https://www.bilibili.com/video/BV1jJ411S7xr?p=15
v
总结
hystrix2种方法处理服务器负载问题
流量监控Dashboard--监控进入服务里面的请求(可以布到客户端)
https://www.bilibili.com/video/BV1jJ411S7xr?p=16
路由网关Zuul
通过网关 统一api调用的地方,可实现请求监控 拦截 等等~~
ZuulApplication
package com;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
@SpringBootApplication
@EnableZuulProxy //zuul注解开启zuul网关
public class ZuulApplication {
public static void main(String[] args) {
SpringApplication.run(ZuulApplication.class, args);
}
}
application.yml
#spring的配置
spring:
application:
name: ZUUL
# 应用服务 WEB 访问端口
server:
port: 9527
#Eureka配置,服务注册到那里
eureka:
client:
service-url: #监控页面 注册地址
defaultZone: http://127.0.0.1:7001/eureka/,http://127.0.0.1:7003/eureka/
instance:
instance-id: zuul9527.com
prefer-ip-address: true
info:
app.name: lucax-zuul
company.name: lucax-company
zuul:
routes:
mydept.serviceId: fw01 #微服务名称 (小写) ----正常调用 http://192.168.108.235:9527/fw01/man
mydept.path: /mydept/** #替换字段 ----修改后也可以这样调用 http://192.168.108.235:9527/mydept/man
ignored-services: fw01 #--------加了这个配置 就不可以使用微服务名称调用 隐藏全部 "*"
prefix: /lucax #设置公共前缀 http://192.168.108.235:9527/lucax/mydept/man
pom.xml
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>ZUUL</artifactId> <version>0.0.1-SNAPSHOT</version> <name>ZUUL</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <spring-boot.version>2.3.7.RELEASE</spring-boot.version> <spring-cloud.version>Hoxton.SR9</spring-cloud.version> </properties> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-zuul</artifactId> <version>1.4.6.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-ribbon</artifactId> <version>1.4.7.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </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> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>${spring-boot.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.1</version> <configuration> <source>1.8</source> <target>1.8</target> <encoding>UTF-8</encoding> </configuration> </plugin> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>2.3.7.RELEASE</version> <configuration> <mainClass>com.XfApplication</mainClass> </configuration> <executions> <execution> <id>repackage</id> <goals> <goal>repackage</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </project>
给zuul 加每个请求调用打印日志的方法
PrintRequestLogFilter
package com.JK; import com.netflix.zuul.ZuulFilter; import com.netflix.zuul.context.RequestContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants; import org.springframework.stereotype.Component; import org.springframework.util.StreamUtils; import javax.servlet.http.HttpServletRequest; import java.io.IOException; import java.io.InputStream; import java.nio.charset.Charset; import java.util.Map; @Component public class PrintRequestLogFilter extends ZuulFilter { private static final Logger LOGGER = LoggerFactory.getLogger(PrintRequestLogFilter.class); @Override public String filterType() { return FilterConstants.POST_TYPE;//要打印返回信息,必须得用"post" } @Override public int filterOrder() { return 0; } @Override public boolean shouldFilter() { return true; } @Override public Object run() { try { RequestContext ctx = RequestContext.getCurrentContext(); HttpServletRequest request = ctx.getRequest(); InputStream in = request.getInputStream(); String reqBbody = StreamUtils.copyToString(in, Charset.forName("UTF-8")); // 打印userId,获取其他用户信息 if (reqBbody != null) { LOGGER.info(reqBbody); // JSONObject json = JSONObject.fromObject(reqBbody); // Object userId = json.get("userId"); // if (userId != null) { // PrintRequestLogFilter.LOGGER.info("request userId:\t" + userId); // } } // 打印请求方法,路径 PrintRequestLogFilter.LOGGER .info("request url:\t" + request.getMethod() + "\t" + request.getRequestURL().toString()); Map<String, String[]> map = request.getParameterMap(); // 打印请求url参数 if (map != null) { StringBuilder sb = new StringBuilder(); sb.append("request parameters:\t"); for (Map.Entry<String, String[]> entry : map.entrySet()) { sb.append("[" + entry.getKey() + "=" + printArray(entry.getValue()) + "]"); } PrintRequestLogFilter.LOGGER.info(sb.toString()); } // 打印请求json参数 if (reqBbody != null) { PrintRequestLogFilter.LOGGER.info("request body:\t" + reqBbody); } // 打印response InputStream out = ctx.getResponseDataStream(); String outBody = StreamUtils.copyToString(out, Charset.forName("UTF-8")); if (outBody != null) { PrintRequestLogFilter.LOGGER.info("response body:\t" + outBody); } ctx.setResponseBody(outBody);//重要!!! } catch (IOException e) { e.printStackTrace(); } return null; } String printArray(String[] arr) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < arr.length; i++) { sb.append(arr[i]); if (i < arr.length - 1) { sb.append(","); } } return sb.toString(); } }