c语言sscanf函数的用法是什么
279
2022-12-31
springcloud gateway如何实现路由和负载均衡
简介:
gateway主要是做路由 负载,过滤 主要是替代zuul 1.x 性能比zuul好 zuul是基于
Servlet ,gateway是基于spring-webflux 用的netty+reactor
yml文件
实现路由 负载 的配置 亲自测试
spring:
application:
name: xgyx_gateway
cloud:
discovery:
locator:
enabled: true
gateway:
routes:
- id: a #随便定义不重复就好
uri: lb://xgyx-welfareservice-x #服务名称
predicates:
- Path=/m/** #前端访问需加入例如 http:ip:port/m
filters:
- StripPrefix=1 #访问后端服务过滤掉m 必填否则找不到后端服务也可以在服务加上统一路径
- name: Hystrix #熔断
args:
name: default
fallbackUri: forward:/defaultfallback #熔断后访问路径
- id: b
uri: lb://xgyx-welfareservice
predicates:
- Path=/welfare/**
filters:
- StripPrefix=1
- name: Hystrix
args:
name: default
fallbackUri: forward:/fallback
#熔断时间
hystrix:
command:
default:
execution:
isolation:
strategy: SEMAPHORE
thread:
timeoutInMilliseconds: 300000 #熔断时间
上面是用了两天时间根据官网上的demo和说明自己测的可以使用 上面 stripPrefix 用的是 PrefixPath 过滤器 其他过滤器使用可以看官网
springcloud gateway 自定义负载均衡
相关类及接口
LoadbalancerClientFilter:使用ribbon负载均衡,默认使用该类(已不推荐使用)
/** @deprecated */
@Deprecated
public class LoadBalancerClientFilter implements GlobalFilter, Ordered {
public static final int LOAD_BALANCER_CLIENT_FILTER_ORDER = 10100;
private static final Log log = LogFactory.getLog(LoadBalancerClientFilter.class);
protected final LoadBalancerClient loadBalancer;
private LoadBalancerProperties properties;
public LoadBalancerClientFilter(LoadBalancerClient loadBalancer, LoadBalancerProperties properties) {
this.loadBalancer = loadBalancer;
this.properties = properties;
}
public int getOrder() {
return 10100;
}
public Mono
URI url = (URI)exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR);
String schemePrefix = (String)exchange.getAttribute(ServerWebExchanghttp://eUtils.GATEWAY_SCHEME_PREFIX_ATTR);
if (url != null && ("lb".equals(url.getScheme()) || "lb".equals(schemePrefix))) {
ServerWebExchangeUtils.addOriginalRequestUrl(exchange, url);
if (log.isTraceEnabled()) {
log.trace("LoadBalancerClientFilter url before: " + url);
}
ServiceInstance instance = this.choose(exchange);
if (instance == null) {
throw NotFoundException.create(this.properties.isUse404(), "Unable to find instance for " + url.getHost());
} else {
URI uri = exchange.getRequest().getURI();
String overrideScheme = instance.isSecure() ? "https" : "http";
if (schemePrefix != null) {
overrideScheme = url.getScheme();
}
URI requestUrl = this.loadBalancer.reconstructURI(new DelegatingServiceInstance(instance, overrideScheme), uri);
if (log.isTraceEnabled()) {
log.trace("LoadBalancerClientFilter url chosen: " + requestUrl);
}
exchange.getAttributes().put(ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR, requestUrl);
return chain.filter(exchange);
}
} else {
return chain.filter(exchange);
}
}
protected ServiceInstance choose(ServerWebExchange exchange) {
return this.loadBalancer.choose(((URI)exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR)).getHost());
}
}
说明:默认使用该类,可通过下述方法使用ReactiveLoadbalancerClientFilter
"You already have RibbonLoadBalancerClient on your classpath. It will be used by default.
As Spring Cloud Ribbon is in maintenance mode. We recommend switching to " + BlockingLoadBalancerClient.class.getSimpleName() + " instead.
In order to use it, set the value of `spring.cloud.loadbalancer.ribbon.enabled` to `false`
or remove spring-cloud-starter-netflix-ribbon from your project."
ReactiveLoadBalancerClientFilter:负载均衡拦截器
public class ReactiveLoadBalancerClientFilter implements GlobalFilter, Ordered {
private static final Log log = LogFactory.getLog(ReactiveLoadBalancerClientFilter.class);
private static final int LOAD_BALANCER_CLIENT_FILTER_ORDER = 10150;
private final LoadBalancerClientFactory clientFactory;
private LoadBalancerProperties properties;
public ReactiveLoadBalancerClientFilter(LoadBalancerClientFactory clientFactory, LoadBalancerProperties properties) {
this.clientFactory = clientFactory;
this.properties = properties;
}
public int getOrder() {
return 10150;
}
public Mono
URI url = (URI)exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR);
String schemePrefix = (String)exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_SCHEME_PREFIX_ATTR);
if (url != null && ("lb".equals(url.getScheme()) || "lb".equals(schemePrefix))) {
//url不为null且协议为lb,或者url以lb开头
ServerWebExchangeUtils.addOriginalRequestUrl(exchange, url);
if (log.isTraceEnabled()) {
log.trace(ReactiveLoadBalancerClientFilter.class.getSimpleName() + " url before: " + url);
}
return this.choose(exchange).doOnNext((response) -> {
//获取ServiceInstance实例,进行一些处理
if (!response.hasServer()) {
//如果没有serviceInstance,直接抛出异常
throw NotFoundException.create(this.properties.isUse404(), "Unable to find instance for " + url.getHost());
} else { //如果有serviceInstance,进行相关处理
URI uri = exchange.getRequest().getURI();
String overrideScheme = null;
if (schemePrefix != null) {
overrideScheme = url.getScheme();
}
DelegatingServiceInstance serviceInstance = new DelegatingServiceInstance((ServiceInstance)response.getServer(), overrideScheme);
URI requestUrl = LoadBalancerUriTools.reconstructURI(serviceInstance, uri);
if (log.isTraceEnabled()) {
log.trace("LoadBalancerClientFilter url chosen: " + requestUrl);
}
exchange.getAttributes().put(ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR, requestUrl);
}
}).then(chain.filter(exchange));
} else {
return chain.filter(exchange); //如果获取不到serviceInstance,直接进行后续过滤
}
}
private Mono
URI uri = (URI)exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR);
ReactorLoadBalancer
if (loadBalancer == null) {
throw new NotFoundException("No loadbalancer available for " + uri.getHost());
} else {
return loadBalancer.choose(this.createRequest());
}
}//选择服务实例
private Request createRequest() {
return ReactiveLoadBalancer.REQUEST;
}
}
ReactorLoadBalancer:负载均衡接口
public interface ReactorLoadBalancer
Mono
default Mono
return this.choose(REQUEST);
}
}
***********************
public interface ReactorServiceInstanceLoadBalancer extends ReactorLoadBalancer
}
RoundRobinLoadbalancer:负载均衡使用轮询
public class RoundRobinLoadBalancer implements ReactorServiceInstanceLoadBalancer {
private static final Log log = LogFactory.getLog(RoundRobinLoadBalancer.class);
private final AtomicInteger position;
private ObjectProvider
private final String serviceId;
************
构造方法
public RoundRobinLoadBalancer(ObjectProvider
public RoundRobinLoadBalancer(ObjectProvider
************
普通方法
public Mono
if (this.serviceInstanceListSupplierProvider != null) {
ServiceInstanceListSupplier supplier = (ServiceInstanceListSupplier)this.serviceInstanceListSupplierProvider.getIfAvailable(NoopServiceInstanceListSupplier::new);
return ((Flux)supplier.get()).next().map(this::getInstanceResponse);
} else {
ServiceInstanceSupplier supplier = (ServiceInstanceSupplier)this.serviceInstanceSupplier.getIfAvailable(NoopServiceInstanceSupplier::new);
return ((Flux)supplier.get()).collectList().map(this::getInstanceResponse);
}
}
private Response
if (instances.isEmpty()) {
log.warn("No servers available for service: " + this.serviceId);
return new EmptyResponse();
} else {
int pos = Math.abs(this.position.incrementAndGet());
ServiceInstance instance = (ServiceInstance)instances.get(pos % instances.size());
return new DefaultResponse(instance);
}
}//使用轮询获取实例
}
示例:
参数id为偶数时,输出hello new version
网关
配置文件
spring:
application:
name: hello-gateway
cloud:
consul:
host: 172.18.0.20
port: 8500
loadbalancer:
ribbon:
enabled: false
gateway:
routes:
- id: myRoute
uri: lb://hello-service
predicates:
- Path=/hello
自定义过滤器
@Component
public class CustomLoadBalancerClientFilter implements GlobalFilter, Ordered {
private static final Log log = LogFactory.getLog(org.springframework.cloud.gateway.filter.ReactiveLoadBalancerClientFilter.class);
@Resource
private final LoadBalancerClientFactory clientFactory;
@Resource
private LoadBalancerProperties properties;
public CustomLoadBalancerClientFilter(LoadBalancerClientFactory clientFactory, LoadBalancerProperties properties) {
this.clientFactory = clientFactory;
this.properties = properties;
}
public int getOrder() {
return 10149;
}
public Mono
URI url = exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR);
String schemePrefix = exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_SCHEME_PREFIX_ATTR);
if (url != null && ("lb".equals(url.getScheme()) || "lb".equals(schemePrefix))) {
ServerWebExchangeUtils.addOriginalRequestUrl(exchange, url);
if (log.isTraceEnabled()) {
log.trace(ReactiveLoadBalancerClientFilter.class.getSimpleName() + " url before: " + url);
}
return this.choose(exchange).doOnNext((response) -> {
if (!response.hasServer()) {
throw NotFoundException.create(this.properties.isUse404(), "Unable to find instance for " + url.getHost());
} else {
URI uri = exchange.getRequest().getURI();
String overrideScheme = null;
if (schemePrefix != null) {
overrideScheme = url.getScheme();
}
int id=Integer.parseInt(Objects.requireNonNull(exchange.getRequest().getQueryParams().getFirst("id")));
if (id%2==0){
while (!"new".equals(response.getServer().getMetadata().get("version"))){
try {
response=this.choose(exchange).toFuture().get();
}catch (Exception e){
System.out.println(e.getMessage());
}
}
}
DelegatingServiceInstance serviceInstance = new DelegatingServiceInstance(response.getServer(), overrideScheme);
System.out.println(exchange.getRequest().getQueryParams().getFirst("id")+"对应server的version为:"+serviceInstance.getMetadata().get("version"));
URI requestUrl = LoadBalancerUriTools.reconstructURI(serviceInstance, uri);
if (log.isTraceEnabled()) {
log.trace("LoadBalancerClientFilter url chosen: " + requestUrl);
}
exchange.getAttributes().put(ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR, requestUrl);
}
}).then(chain.filter(exchange));
} else {
return chain.filter(exchange);
}
}
private Mono
URI uri = exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR);
ashttp://sert uri != null;
ReactorLoadBalancer
if (loadBalancer == null) {
throw new NotFoundException("No loadbalancer available for " + uri.getHost());
} else {
return loadBalancer.choose(this.createRequest());
}
}
private Request createRequest() {
return ReactiveLoadBalancer.REQUEST;
}
}
同名应用hello-service1
配置文件
spring:
application:
name: hello-service
cloud:
consul:
host: 172.18.0.20
port: 8500
discovery:
instance-id: ${spring.application.name}-${random.int}
tags: version=old
controller 层
@RestController
public class HelloController {
@RequestMapping("/hello")
public String hello(){
return "hello old version";
}
}
同名应用hello-service2
配置文件
spring:
application:
name: hello-service
cloud:
consul:
host: 172.18.0.20
port: 8500
discovery:
instance-id: ${spring.application.name}-${random.int}
tags: version=new
controller 层
@RestController
public class HelloController {
@RequestMapping("/hello")
public String hello(){
return "hello new version";
}
}
测试输出
consul注册的应用
参数测试
当id为偶数时,输出为hello new version
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~