1、网关服务加入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
2、ZuulApplication.java
@EnableDiscoveryClient
@SpringBootApplication
@EnableFeignClients
@EnableZuulProxy
public class ZuulApplication {
public static void main(String[] args) {
SpringApplication.run(ZuulApplication.class, args);
}
}
3.zuul服务的配置文件
server:
port: 8436
spring:
datasource:
driver-class-name: org.postgresql.Driver
url: jdbc:postgresql://localhost:5432/zgm
username: postgres
password: 123456
zuul:
routes:
user:
path: /user/**
serviceId: userService
userService: #这个服务名就是serviceId对应值
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule #配置随机策略,默认轮播策略
feign:
client:
config:
default:
connectTimeout: 60000
readTimeout: 60000
hystrix:
enabled: true
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 122000
ribbon:
MaxAutoRetries: 0
OkToRetryOnAllOperations: false
ReadTimeout: 60000
SocketTimeout: 60000
因为zuul本身就集成了hystrix和ribbon,所以我们写一下配置文件就可以直接用了,十分方便。
4、熔断回滚处理
ClientFallbackProvider.java
import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.stereotype.Component;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
/**
* @Author ZGM
* @DateTime 2022/6/20
* @description
*/
@Component
public class ClientFallbackProvider implements FallbackProvider {
@Override
public String getRoute() {
return "userService"; //接口中getRoute指的是此处理工具处理那个微服务。假如返回null或者*表示处理所有的微服务
}
/**
* 回退逻辑
* @param route
* @param cause
* @return
*/
@Override
public ClientHttpResponse fallbackResponse(String route, Throwable cause) {
return new ClientHttpResponse() {
@Override
public HttpStatus getStatusCode() throws IOException {
return HttpStatus.BAD_GATEWAY;
}
@Override
public int getRawStatusCode() throws IOException {
return HttpStatus.OK.value(); //http状态码可自己更改
}
@Override
public String getStatusText() throws IOException {
return HttpStatus.OK.getReasonPhrase();
}
@Override
public void close() {
}
@Override
public InputStream getBody() throws IOException {
//return new ByteArrayInputStream(("fallback-base-producer:" + ClientFallbackProvider.this.getRoute()).getBytes());
return new ByteArrayInputStream(("系统异常").getBytes());
}
@Override
public HttpHeaders getHeaders() {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
return headers;
}
};
}
}
5、User服务在两个端口号启动,验证负载均衡和熔断处理
5.1、nacos的某个命名空间下,新建userServices.yml文件
server:
port: 8433
servlet:
context-path: /userservice
application-display-name: userService
spring:
application:
name: userService
datasource:
driver-class-name: org.postgresql.Driver
url: jdbc:postgresql://localhost:5432/zgm
username: postgres
password: 123456
jpa:
show-sql: true
5.2、在两个端口号上启动User服务
5.2.1、服务的配置文件,bootstrap-zgm.yml
spring:
application:
name: userService #与dataid名字去掉尾缀相同
cloud:
nacos:
discovery: #服务的发现地址
server-addr: 121.4.229.39:8848
namespace: 40384e20-8db1-4d97-a179-ce5a7b707a58 #命名空间的id
config:
enabled: true #开启nacos配置,默认为true
server-addr: 121.4.229.39:8848 #p配置文件的注册地址
file-extension: yml #dataid就是application.name和file-extensiona的拼接
namespace: 40384e20-8db1-4d97-a179-ce5a7b707a58 #命名空间id
group: DEFAULT_GROUP #分组,默认是DEFAULT_GROUP
# ext-config[0]: #扩展其他配置文件以数组形式表示
# data-id: nacos-service2.yml
# group: DEFAULT_GROUP
# refresh: true #动态刷新
5.2.2配置端口号步骤
点箭头 ->edit configuration
5.2.3、启动UserApplication,然后修改userServices.yml里的端口号,在新建一个UserApplication1的实例,配置与UserApplication一样,最后启动。
这样userService服务下就有两个实例
5.3在user服务里写个接口来获取当前服务的端口号
UserController.java
@RestController
@RequestMapping("/v1/user")
public class UserController {
@Value("${server.port}")
private String port;
@GetMapping("/index")
public Resp index(){
return Resp.success("当前端口号为:" + port);
}
}
5.4、通过网关调用此接口
去掉网关服务的配置文件里的这段,每次调用接口都是轮流调用两个实例,即达到了负载均衡的效果。加上这段配置,就是随机策略,可能连续调好几次都是同一个实例。
userService: #这个服务名就是serviceId对应值
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule #配置随机策略,默认轮播策略
5.5、熔断处理的实现
user服务的两个实例全都停止运行了,也就是服务挂掉了,在调用上面接口就会出现如下情况
这里的http状态码以及返回结果都是我在上面的ClientFallbackProvider.java里自己定义的,可自己修改。