API网关spring cloud gateway和负载均衡框架ribbon实战
2020-12-13 04:14
标签:抽象类 imp border 负载均衡算法 conf resources 访问 列表 temp 通常我们如果有一个服务,会部署到多台服务器上,这些微服务如果都暴露给客户,是非常难以管理的,我们系统需要有一个唯一的出口,API网关是一个服务,是系统的唯一出口。API网关封装了系统内部的微服务,为客户端提供一个定制的API。客户端只需要调用网关接口,就可以调用到实际的微服务,实际的服务对客户不可见,并且容易扩展服务。 API网关可以结合ribbon完成负载均衡的功能,可以自动检查微服务的状况,及时剔除或者加入某个微服务到可用服务列表。此外网关可以完成权限检查、限流、统计等功能。下面我们将一一完成上面的功能。注意微服务只是提供rest的接口,不会有额外的组件依赖,不需要eureka等。只需要两个工程,一个是微服务,我们可以部署到多台服务器,那么只是访问的ip不同,在演示的时候,我们在本机演示,修改端口,达到启动多个微服务的目的,另一个就是网关,主要是spring cloud gateway 和 ribbon两大组件来实现网关和负载均衡等功能。 1、创建一个父工程 删除src目录 pom文件增加如下内容: 2、新建一个module 3、修改pom.xml文件,增加如下内容: 4、在resources文件夹下面增加一个application.yml文件,内容为: 5、新增一个主入口类Provider1001Application,内容如下 6、新增一个rest接口HelloWorldController,内容如下: 7、启动main方法,在浏览器输入http://localhost:1001/hello可以看到: 8、同理,我们再建立2个rest服务,步骤如下 (1)新增module,参考第二小节,主要把名称改为: (2)pom.xml文件参考第三小节,加上即可。 (3)参考第四小节,新建application.yml文件,注意端口改为 (4)参考第五小节,新建一个主启动类,名称为如下,内容都一样。 (5)参考第六小节,新增一个HelloWorldController接口,其中只有下面这句中的 1001 改为 1002 或 1003,方便测试观察结果 (6)参考第7小节测试成功新增的两个服务即可。 (7)现在的工程如下: Spring Cloud Gateway是Spring官方基于Spring 5.0,Spring Boot 2.0和Project Reactor等技术开发的网关,Spring Cloud Gateway旨在为微服务架构提供一种简单而有效的统一的API路由管理方式。 1、新建一个module,按照上面的方式,名称叫: gateway 2、添加依赖 3、新建一个主启动类 GatewayApplication 4、新增一个application.yml文件,内容如下: 5、测试 访问 http://localhost:8080/gateway/hello 上面只是简单的路由转发,可以先了解下工作原理: url 中的 http://localhost:8080/ 会访问到gateway这个服务,spring cloud gateway会在配置的路由中做谓词匹配,也就是url中的gateway匹配到了id为my_route的路由,就会把http://localhost:8080/替换为http://localhost:1001/,并且filters中的规则(StripPrefix)会把http://localhost:8080/gateway/hello中的gateway去掉,那么http://localhost:8080/gateway/hello实际就会去访问http://localhost:1001/hello,也就是访问到了provider1001服务。 疑问? 上面的uri只配置了provider1001服务,如何使用geteway访问三个服务呢?需要使用负载均衡ribbon 下面的操作都是在gateway这个服务操作的: 1、添加依赖 2、修改配置文件,增加或者修改见红色部分 3、重启gateway服务,不断访问 http://localhost:8080/gateway/hello,发现可以不断访问的时候在三个服务中来回切换,达到了负载均衡的目的。上面我们使用了轮询的负载均衡策略。 注意: 疑问: 如果上面listOfServers中的任何一个服务关闭了,然后使用gateway访问,会出现什么情况? 事实是这样的: 比如provider1003服务宕机。那么使用轮询算法的时候,不断访问gateway,会出现: provider1001 正常,provider1002 正常,provider1003 异常,provider1001 正常,provider1002 正常,provider1003 异常。。。 provider1003 已经宕机,但是请求还是不断转发到该服务上,导致服务访问的过程中,部分请求异常。
我们需要有这样的功能,如果某个服务宕机,那么请求就不会发送到该服务器上,如果宕机的服务器恢复了,那么请求又可以发送到该服务器上,要实现这个功能,需要ribbon对服务进行健康检查。 (1)首先微服务需要有个rest接口,就叫做heath接口吧,调用heath接口返回ok表明服务正常。 (2)gateway需要有调用heath接口的功能,并且配置到ribbon可以不断调用该接口,时刻检查服务的状态,如果有服务器挂掉,可以很快感知到,并把该服务剔除可用服务列表。 1、provider1001,provider1002,provider1003增加一个rest接口HealthController 2、在gateway工程里面做如下修改 (1)新建一个Config类 (2)新建一个健康检查的类,主要是调用heath接口。 上面代码继承IPing接口,判断服务是否可用。我们在微服务中增加heath接口,在gateway中调用该接口,如果返回正常则认为微服务可用。 (3)修改配置文件,注意最后一行,这是唯一增加的。 3、重新启动微服务和gateway服务,然后通过网关访问,可以看到可以正常访问,如果此时把某一台微服务停掉,访问的时候开始可能会报错,但是随着健康检查的运行,检测到该服务不可用,则会把该服务剔除,以后只会访问正常运行的服务。当宕机的服务重启,健康检查还会把该服务加入到可用服务列表,下次请求就会再次发送到该服务上。 上面演示了随机、轮询等负载均衡算法,我们可以自定义负载均衡算法。需求是:每个服务器访问三次再跳转到下一个服务器。 只需要在gateway项目中实现AbstractLoadBalancerRule抽象类,然后配置到下面即可 1、负载均衡算法(参考RandomRule) 2、修改配置 3、重启gateway,然后访问http://localhost:8080/gateway/hello不断点击,发现点击三次就会调整到下一个服务。 API网关spring cloud gateway和负载均衡框架ribbon实战 标签:抽象类 imp border 负载均衡算法 conf resources 访问 列表 temp 原文地址:https://www.cnblogs.com/ye-feng-yu/p/11106006.html1、rest服务构建
parent>
groupId>org.springframework.bootgroupId>
artifactId>spring-boot-starter-parentartifactId>
version>2.1.3.RELEASEversion>
parent>
dependencies>
dependency>
groupId>org.springframework.bootgroupId>
artifactId>spring-boot-starter-webartifactId>
dependency>
dependencies>
server:
port: 1001
package com.yefengyu.cloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Provider1001Application
{
public static void main(String[] args)
{
SpringApplication.run(Provider1001Application.class, args);
}
}
package com.yefengyu.cloud.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloWorldController
{
@GetMapping("/hello")
@ResponseBody
public String hello()
{
return "hello spring cloud, 1001";
}
}
return "hello spring cloud, 1001";
2、spring cloud gateway
dependencies>
dependency>
groupId>org.springframework.cloudgroupId>
artifactId>spring-cloud-starter-gatewayartifactId>
version>2.1.0.RELEASEversion>
dependency>
dependencies>
package com.yefengyu.gateway;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class GatewayApplication
{
public static void main(String[] args)
{
SpringApplication.run(GatewayApplication.class, args);
}
}
server:
port: 8080
spring:
application:
name: gateway_server
cloud:
gateway:
default-filters:
routes:
- id: my_route
uri: http://localhost:1001/
predicates:
- Path=/gateway/**
filters:
- StripPrefix=1
3、ribbon负载均衡
dependency>
groupId>org.springframework.cloudgroupId>
artifactId>spring-cloud-starter-netflix-ribbonartifactId>
version>2.1.0.RELEASEversion>
dependency>
server:
port: 8080
spring:
application:
name: gateway_server
cloud:
gateway:
default-filters:
routes:
- id: my_route
uri: lb://my-load-balanced-service
predicates:
- Path=/gateway/**
filters:
- StripPrefix=1
my-load-balanced-service:
ribbon:
listOfServers: localhost:1001, localhost:1002,localhost:1003
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RoundRobinRule
4、健康检查
package com.yefengyu.cloud.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HealthController
{
@GetMapping("/heath")
@ResponseBody
public String heath()
{
return "ok";
}
}
package com.yefengyu.gateway.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
@Configuration
public class MainConfig
{
@Bean
public RestTemplate restTemplate()
{
return new RestTemplate();
}
}
package com.yefengyu.gateway.loadbanlance;
import com.netflix.loadbalancer.IPing;
import com.netflix.loadbalancer.Server;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
@Component
public class HealthExamination implements IPing
{
@Autowired
private RestTemplate restTemplate;
@Override
public boolean isAlive(Server server)
{
String url = "http://" + server.getId() + "/heath";
try
{
ResponseEntity
server:
port: 8080
spring:
application:
name: gateway_server
cloud:
gateway:
default-filters:
routes:
- id: my_route
uri: lb://my-load-balanced-service
predicates:
- Path=/gateway/**
filters:
- StripPrefix=1
my-load-balanced-service:
ribbon:
listOfServers: localhost:1001,localhost:1002,localhost:1003
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RoundRobinRule
NFLoadBalancerPingClassName: com.yefengyu.gateway.loadbanlance.HealthExamination
5、自定义负载均衡策略
package com.yefengyu.gateway.loadbanlance;
import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.AbstractLoadBalancerRule;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.Server;
import java.util.ArrayList;
import java.util.List;
public class MyRule extends AbstractLoadBalancerRule
{
private volatile int total;
private volatile int index;
List
文章标题:API网关spring cloud gateway和负载均衡框架ribbon实战
文章链接:http://soscw.com/essay/29198.html