Apache ShenYu网关初体验

前言

Apache ShenYu(神禹)是采用Java WebFlux编写的响应式API网关,具有异步、高性能、跨语言的特点。

  • 支持HTTP、Dubbo、 Spring Cloud、 gRPC、 Motan、 Sofa、 Tars 等协议
  • 采用插件化设计思想,插件热插拔,易扩展
  • 灵活的流量筛选,能满足各种流量控制
  • 内置鉴权、限流、熔断、防火墙等插件
  • 流量配置动态化,性能极高
  • 支持集群部署,支持A/B测试、蓝绿发布

架构图

image.png

快速部署

Apache Shenyu 支持本地部署、单机快速部署、二进制包部署、Docker部署、K8s部署、集群部署等,为了能够快速体验,我们使用本地部署,同时也为了方便后期看源码。

环境准备

  • 本地正确安装JDK1.8+
  • 本地正确安装Git
  • 本地正确安装Maven
  • 选择一款开发工具,比如IDEA

下载编译代码

  1. https://github.com/apache/shenyu.git下载最新仓库,下载完成后使用mvn clean install -Dmaven.javadoc.skip=true -B -Drat.skip=true -Djacoco.skip=true -DskipITs -DskipTests编译打包一下。
  2. 导入IDEA,切换分支到最小的release版本,我这目前为 2.5.0-release
  3. 使用开发工具启动 org.apache.shenyu.admin.ShenyuAdminBootstrap,访问 http://localhost:9095 , 默认用户名和密码分别为: admin123456(默认使用H2数据库),这是Shenyu运维管理后台。
  4. 使用开发工具启动 org.apache.shenyu.bootstrap.ShenyuBootstrapApplication,这就相当于微服务网关

如下是管理后台截图:

image.png

官网的git地址有误:https://github.com/apache/incubator-shenyu.git

微服务集成

前期准备:nacos服务,搭建步骤看nacos官网
版本关系:

<shenyu.version>2.4.3</shenyu.version>
<boot.version>2.2.2.RELEASE</boot.version>
<cloud.version>Hoxton.SR8</cloud.version>
<nacos.version>2.2.6.RELEASE</nacos.version>

版本管理(统一加到父级pom中):

<dependencyManagement>
    <dependencies>
        <dependency>
            <!-- Import dependency management from Spring Boot -->
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>${boot.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>${cloud.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

创建网关

  1. 创建网关服务shenyu-gateway,依赖的pom.xml如下
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-webflux</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

<!--shenyu-->
<!--shenyu gateway start-->
<dependency>
    <groupId>org.apache.shenyu</groupId>
    <artifactId>shenyu-spring-boot-starter-gateway</artifactId>
    <version>${shenyu.version}</version>
</dependency>

<dependency>
    <groupId>org.apache.shenyu</groupId>
    <artifactId>shenyu-spring-boot-starter-plugin-springcloud</artifactId>
    <version>${shenyu.version}</version>
</dependency>

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-commons</artifactId>
    <version>2.2.5.RELEASE</version>
</dependency>

<dependency>
    <groupId>org.apache.shenyu</groupId>
    <artifactId>shenyu-spring-boot-starter-plugin-httpclient</artifactId>
    <version>${shenyu.version}</version>
</dependency>

<dependency>
    <groupId>org.apache.shenyu</groupId>
    <artifactId>shenyu-spring-boot-starter-instance</artifactId>
    <version>${shenyu.version}</version>
</dependency>

<!--nacos-->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    <version>${nacos.version}</version>
</dependency>

<!-- apache shenyu data sync start use nacos-->
<dependency>
    <groupId>org.apache.shenyu</groupId>
    <artifactId>shenyu-spring-boot-starter-sync-data-nacos</artifactId>
    <version>${shenyu.version}</version>
</dependency>
  1. application.yml配置如下:
server:
  port: 7000

spring:
  cloud:
    nacos:
      server-addr: 127.0.0.1:8848
    discovery:
      enabled: true
  main:
    allow-bean-definition-overriding: true
    allow-circular-references: true
  codec:
      max-in-memory-size: 2MB
  application:
    name: shenyu-gateway

shenyu:
  sync:
    nacos:
      url: ${spring.cloud.nacos.server-addr}
      # url: 配置成你的 nacos地址,集群环境请使用(,)分隔。
      namespace: sync-data

  1. GatewayApplication代码
@EnableDiscoveryClient
@SpringBootApplication
public class GatewayApplication {

    public static void main(String[] args) {
        SpringApplication.run(GatewayApplication.class, args);
    }

}

通常如上三步,已经集成了shenyu-gateway服务。
启动完成日志,可以清楚的看到Shenyu的Logo:

2022-08-26 00:42:11.706  INFO 2300 --- [           main] org.apache.shenyu.web.logo.ShenyuLogo    : 


   _____ _                            
  / ____| |                           
 | (___ | |__   ___ _ __  _   _ _   _ 
  \___ \| '_ \ / _ \ '_ \| | | | | | |
  ____) | | | |  __/ | | | |_| | |_| |
 |_____/|_| |_|\___|_| |_|\__, |\__,_|
                           __/ |      
                          |___/       
 :: Shenyu :: (v2.4.3)


  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.2.2.RELEASE)

2022-08-26 00:42:13.111  INFO 2300 --- [           main] c.s.demo.gateway.GatewayApplication      : No active profile set, falling back to default profiles: default
...省略
2022-08-26 00:42:21.644  INFO 2300 --- [           main] o.s.b.web.embedded.netty.NettyWebServer  : Netty started on port(s): 7000
2022-08-26 00:42:22.363  INFO 2300 --- [           main] c.a.c.n.registry.NacosServiceRegistry    : nacos registry, DEFAULT_GROUP shenyu-gateway 192.168.0.115:7000 register finished
2022-08-26 00:42:23.104  INFO 2300 --- [           main] c.s.demo.gateway.GatewayApplication      : Started GatewayApplication in 12.584 seconds (JVM running for 13.613)

💡 配置依赖的坑,已经给你踩好了,务必按照如上配置

移植ShenYu管理后台

  1. 从Apache ShenYu源码复制一份
  2. 修改application.yml的注册地址和同步地址,完整配置如下
server:
  port: 9095
  address: 0.0.0.0

spring:
  profiles:
    active: h2
  thymeleaf:
    cache: true
    encoding: utf-8
    enabled: true
    prefix: classpath:/static/
    suffix: .html

mybatis:
  config-location: classpath:/mybatis/mybatis-config.xml
  mapper-locations: classpath:/mappers/*.xml

shenyu:
  register:
    registerType: nacos #http #zookeeper #etcd #nacos #consul
    serverLists: 127.0.0.1:8848 #localhost:2181 #http://localhost:2379 localhost:8848
    props:
      sessionTimeout: 5000
      connectionTimeout: 2000
      checked: true
      zombieCheckTimes: 5
      scheduledTime: 10
      nacosNameSpace: ShenyuRegisterCenter
  sync:
#    websocket:
#      enabled: true
#      messageMaxSize: 10240
#      zookeeper:
#        url: localhost:2181
#        sessionTimeout: 5000
#        connectionTimeout: 2000
#      http:
#        enabled: true
      nacos:
        url: 127.0.0.1:8848
        namespace: sync-data
#        username:
#        password:
#        acm:
#          enabled: false
#          endpoint: acm.aliyun.com
#          namespace:
#          accessKey:
#          secretKey:
#    etcd:
#      url: http://localhost:2379
#    consul:
#      url: http://localhost:8500
  ldap:
    enabled: false
    url: ldap://xxxx:xxx
    bind-dn: cn=xxx,dc=xxx,dc=xxx
    password: xxxx
    base-dn: ou=xxx,dc=xxx,dc=xxx
    object-class: person
    login-field: cn
  jwt:
    expired-seconds: 86400000
  shiro:
    white-list:
      - /
      - /favicon.*
      - /static/**
      - /index**
      - /platform/login
      - /websocket
      - /error
      - /actuator/health
      - /swagger-ui.html
      - /webjars/**
      - /swagger-resources/**
      - /v2/api-docs
      - /csrf
  swagger:
    enable: true

logging:
  level:
    root: info
    org.springframework.boot: info
    org.apache.ibatis: info
    org.apache.shenyu.bonuspoint: info
    org.apache.shenyu.lottery: info
    org.apache.shenyu: info

💡 ShenYu的管理后台不需要做什么修改,只要调整配置即可

创建服务

为了测试效果,我们创建一个server1的服务,一会在Docker中多实例部署

  1. pom.xml依赖
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
        <groupId>org.apache.shenyu</groupId>
        <artifactId>shenyu-spring-boot-starter-client-springcloud</artifactId>
        <version>${shenyu.version}</version>
    </dependency>

    <!--nacos-->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        <version>${nacos.version}</version>
    </dependency>

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-commons</artifactId>
        <version>2.2.5.RELEASE</version>
    </dependency>
</dependencies>
  1. application.yml配置
server:
  port: 8080

spring:
  cloud:
    nacos:
      server-addr: 127.0.0.1:8848
    discovery:
      enabled: true
  main:
    #允许覆盖bean
    allow-bean-definition-overriding: true
  codec:
    #编码器缓存限制
    max-in-memory-size: 2MB
  application:
    name: server1

shenyu:
  register:
    registerType: nacos #zookeeper #etcd #nacos #consul
    serverLists: ${spring.cloud.nacos.server-addr} #localhost:2181 #http://localhost:2379 #localhost:8848
    props:
      nacosNameSpace: ShenyuRegisterCenter
  client:
    springCloud:
      props:
        contextPath: /server1

  1. 创建一个测试接口
@RestController
public class HelloController {

    @PostMapping("/hello")
    public String hello() {
        log.info("ip:{}", InetAddress.getLocalHost().getHostAddress());
        return "Server1 Hello ShenYu";
    }
}
  1. Docker配置
# 指定 java 环境镜像
FROM java:8
# 复制文件到容器
COPY target/*.jar /application.jar

RUN /bin/cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo 'Asia/Shanghai' > /etc/timezone

ENTRYPOINT ["java", "-jar", "-Xms256m", "-Xmx256m", "/application.jar"]

体验

1.分别启动shenyu-gatewayshenyu-admin、docker部署两个server1实例
image.png

  1. 配置路由测试

image.png

配置意思是:当请求头server=server1时,会请求到172.17.0.4 这个服务上
同理配置server2

image.png
配置rule,ruel的规则我们配置为都通过,使用or

image.png
使用Postman请求网关地址[http://localhost:7000/hello](http://localhost:63193/hello),成功返回了结果Server1 Hello ShenYu

image.png
同时shenyu-gateway打印了路由日志

INFO 1 --- [u-netty-epoll-3] o.a.s.plugin.base.AbstractShenyuPlugin   : divide selector success match , selector name :server1
INFO 1 --- [u-netty-epoll-3] o.a.s.plugin.base.AbstractShenyuPlugin   : divide rule success match , rule name :full rule
INFO 1 --- [u-netty-epoll-3] o.a.s.p.h.AbstractHttpClientPlugin       : The request urlPath is http://172.17.0.4:8080/hello, retryTimes is 3, retryStrategy is current

Apache ShenYu体验完毕,后面将继续推出选择器、规则相关文章,敬请期待。

💡 项目源码地址:https://github.com/jujunchen/shenyu-demo.git

shenyu网关是一款开源的API网关软件,它可以帮助开发者实现对接口的统一管理和流量控制。shenyu网关提供了多种功能,包括请求转发、请求过滤、流量限制、负载均衡等,帮助用户实现高可用和高稳定性的系统架构。 shenyu网关基于Java开发,使用简单方便,支持多种开源框架和中间件,如Spring Boot、Dubbo、Motan等。通过使用shenyu网关,开发者可以快速搭建起一个完善的微服务架构,可以轻松地管理和监控各个微服务之间的通信和流量。 另外,shenyu网关还提供了可视化的管理界面,方便用户进行参数配置、资源管理、性能监控等操作。用户可以通过该界面对各个服务进行细粒度的管理,实现功能的灵活配置和动态调整。 码云是中国最大的代码托管平台,类似于国外的GitHub。用户可以通过码云托管自己的代码仓库,并利用这个平台进行团队协作和项目管理。码云提供了Git版本控制、代码托管、代码审查等功能,支持多种开发语言和开发工具。 与GitHub不同的是,码云在国内具有更好的访问速度和稳定性,同时还提供了国内常用的Git代码托管服务,支持国内的开发者更方便地使用和访问。用户可以在码云上创建自己的项目仓库,与其他开发者进行交流学习,并共同进行开发和维护。 综上所述,shenyu网关和码云都是开发者常用的工具。shenyu网关可以帮助开发者实现API网关的功能,提供统一的接口管理和流量控制;码云则是代码托管平台,提供代码的版本控制和团队协作功能。两者的结合可以帮助开发者更好地进行微服务架构的开发和管理。
评论 44
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿提说说

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值