你好! 感谢使用soul,这篇文章主要关注soul开发环境搭建,用于soul初学者,讲解SpringCloud相关集成。
soul官网地址:https://dromara.org/zh-cn/docs/soul/soul.html
soul git地址:https://github.com/Dromara/soul
Soul 是基于 WebFlux 实现的响应式的 API 网关,具有异步、高性能、跨语言等特点。目前 Soul 功能列表如下:
支持各种语言,无缝集成Dubbo,SpringCloud。
丰富的插件支持,鉴权,限流,熔断,防火墙等等。
网关多种规则动态配置,支持各种策略配置。
插件热插拔,易扩展。
支持集群部署,支持A/B Test。
Soul 部署包含以下部分:
MySQL 安装,配置soul数据库;
redis配置;
管理台soul-admin配置部署;
网关soul-bootstrap+nacos配置部署。
1、Myql安装,这部分不是重点,略过,相信大家都会;
2、配置soul数据库,下载soul源码,在项目的script目录下找到soul.sql文件,执行到Mysql。
redis部署大家自己百度,不属于这篇文章内容。
因为soul-bootstrap启动时,会报 Connection refused: localhost/127.0.0.1:6379 错误,这是
Soul 限流功能需要使用到 Redis,可以暂时忽略。考虑到看到报错的强迫症,可以安装redis,配置redis消除
报错信息。
git上拉取soul最新版本源码,找到soul-admin.
配置相应的环境,读取对应的配置文件,我演示的dev环境,文件如下:
spring:
profiles:
active: dev
修改soul数据库信息,包含地址、账号和密码,具体如下:
spring:
thymeleaf:
cache: true
encoding: utf-8
enabled: true
prefix: classpath:/static/
suffix: .html
datasource:
url: jdbc:mysql://localhost:3306/soul?useUnicode=true&characterEncoding=UTF-8&useSSL=false&autoReconnect=true&failOverReadOnly=false&&serverTimezone=UTC
username: root
password: root
dbcp2:
driver-class-name: com.mysql.jdbc.Driver
修改同步策略,soul数据同步支持zookeeper方式、http长轮询和websocket方式 (默认方式,推荐)三种方式,三种同步策略优劣参考soul同步策略官网。
开发环境我配置的是http长轮询方式,大家可以尝试其他方式,但是zookeeper方式麻烦一些。
#1、zookeeper方式同步
#soul:
# sync:
# strategy: zookeeper
# zookeeper:
# url: localhost:2181
# sessionTimeout: 5000
# connectionTimeout: 2000
#
#2、http长轮询
soul:
sync:
strategy: http
#3、websocket方式 (默认方式,推荐)
#soul:
# sync:
# strategy: websocket
配置信息调整后,开始启动项目,执行 DemoApplication 启动 Spring Boot 应用。在 IDEA 控制台可以看到如下日志,看到写入 HTTP API 方法的元数据到 Soul Admin 控制台。启动日志如下:
2020-05-28 10:40:41.401 DEBUG 12596 --- [ main] o.d.s.a.mapper.SelectorMapper.selectAll : ==> Preparing: select id, date_created, date_updated, plugin_id, name, match_mode, type, sort, enabled, loged, continued,handle from selector
2020-05-28 10:40:41.402 DEBUG 12596 --- [ main] o.d.s.a.mapper.SelectorMapper.selectAll : ==> Parameters:
2020-05-28 10:40:41.404 DEBUG 12596 --- [ main] o.d.s.a.mapper.SelectorMapper.selectAll : <== Total: 1
2020-05-28 10:40:41.405 DEBUG 12596 --- [ main] o.d.s.a.m.S.selectByQuery : ==> Preparing: select id, date_created, date_updated, selector_id, param_type, operator, param_name, param_value from selector_condition where selector_id = ?
2020-05-28 10:40:41.406 DEBUG 12596 --- [ main] o.d.s.a.m.S.selectByQuery : ==> Parameters: 1265573822687797248(String)
2020-05-28 10:40:41.408 DEBUG 12596 --- [ main] o.d.s.a.m.S.selectByQuery : <== Total: 1
2020-05-28 10:40:41.409 DEBUG 12596 --- [ main] o.d.s.a.mapper.PluginMapper.selectById : ==> Preparing: select id, date_created, date_updated, name,config,role, enabled from plugin where id = ?
2020-05-28 10:40:41.409 DEBUG 12596 --- [ main] o.d.s.a.mapper.PluginMapper.selectById : ==> Parameters: 8(String)
2020-05-28 10:40:41.411 DEBUG 12596 --- [ main] o.d.s.a.mapper.PluginMapper.selectById : <== Total: 1
2020-05-28 10:40:41.415 DEBUG 12596 --- [ main] o.d.s.a.mapper.MetaDataMapper.selectAll : ==> Preparing: select id, date_created, date_updated, app_name, path,path_desc,rpc_type, service_name,method_name,parameter_types,rpc_ext,enabled from meta_data
2020-05-28 10:40:41.415 DEBUG 12596 --- [ main] o.d.s.a.mapper.MetaDataMapper.selectAll : ==> Parameters:
2020-05-28 10:40:41.417 DEBUG 12596 --- [ main] o.d.s.a.mapper.MetaDataMapper.selectAll : <== Total: 2
2020-05-28 10:40:41.421 INFO 12596 --- [ main] f.a.AutowiredAnnotationBeanPostProcessor : Inconsistent constructor declaration on bean with name 'httpServiceDiscovery': single autowire-marked constructor flagged as optional - this constructor is effectively required since there is no default constructor to fall back to: public org.dromara.soul.admin.listener.zookeeper.HttpServiceDiscovery(org.dromara.soul.admin.service.SelectorService,org.dromara.soul.admin.mapper.SelectorMapper,org.springframework.context.ApplicationEventPublisher,org.springframework.core.env.Environment)
2020-05-28 10:40:41.956 INFO 12596 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
2020-05-28 10:40:42.262 INFO 12596 --- [ main] o.s.b.a.w.s.WelcomePageHandlerMapping : Adding welcome page: class path resource [static/index.html]
2020-05-28 10:40:42.945 INFO 12596 --- [ main] o.s.b.a.e.web.EndpointLinksResolver : Exposing 2 endpoint(s) beneath base path '/actuator'
2020-05-28 10:40:43.078 INFO 12596 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8082 (http) with context path ''
2020-05-28 10:40:43.083 INFO 12596 --- [ main] o.d.soul.admin.SoulAdminApplication : Started SoulAdminApplication in 17.778 seconds (JVM running for 22.724)
2020-05-28 10:40:45.125 INFO 12596 --- [(3)-10.0.23.129] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
2020-05-28 10:40:45.125 INFO 12596 --- [(3)-10.0.23.129] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
2020-05-28 10:40:45.138 INFO 12596 --- [(3)-10.0.23.129] o.s.web.servlet.DispatcherServlet : Completed initialization in 13 ms
使用浏览器,访问 http://localhost:8082/#/user/login地址,进入登录页面,输入账号admin,密码123456登录。
nacos相关信息参考nacos官网和git地址。
配置相应的环境,读取对应的配置文件,我演示的dev环境,文件如下:
spring:
profiles:
active: dev
文件包含注册中心配置和数据同步策略配置,注册中心配置如下:
spring:
main:
allow-bean-definition-overriding: true
application:
name: soul-bootstrap
cloud:
nacos: #配置nacos注册中心
discovery:
server-addr: 127.0.0.1:8848 #nacos地址
数据同步策略配置如下(配置的是http长轮询,注意:需要保持与soul-admin同步策略一致,具体参考soul同步策略官网):
soul:
sync:
strategy: http #同步策略
http:
url: http://localhost:8082 #soul-admin服务地址
修改 pom.xml 文件,引入 spring-cloud-starter-alibaba-nacos-discovery 依赖,集成 Nacos 作为 Spring Cloud 的注册中心,文件如下:
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>soul</artifactId>
<groupId>org.dromara</groupId>
<version>2.1.2-RELEASE</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>soul-bootstrap</artifactId>
<dependencies>
<dependency>
<groupId>org.dromara</groupId>
<artifactId>soul-spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-commons</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.netflix.archaius</groupId>
<artifactId>archaius-core</artifactId>
<version>0.7.6</version>
<exclusions>
<exclusion>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- <dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
<version>2.0.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-commons</artifactId>
<version>2.0.0.RELEASE</version>
</dependency>-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>2.2.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.projectreactor</groupId>
<artifactId>reactor-spring</artifactId>
<version>1.0.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--dubbo start-->
<!--<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo</artifactId>
<version>2.7.5</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-registry-nacos</artifactId>
<version>2.7.5</version>
</dependency>-->
<!-- Keep latest Nacos client version -->
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
<version>1.2.0</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-client</artifactId>
<version>4.0.1</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>4.0.1</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>4.0.1</version>
</dependency>
<!--dubbo end-->
</dependencies>
<!--多环境 Maven profile整合Spring profile-->
<profiles>
<profile>
<id>local</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<env>local</env>
</properties>
</profile>
<profile>
<id>dev</id>
<properties>
<env>dev</env>
</properties>
</profile>
<profile>
<id>prod</id>
<properties>
<env>prod</env>
</properties>
</profile>
</profiles>
<build>
<finalName>soul-bootstrap</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<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>
<configuration>
<mainClass>org.dromara.soul.bootstrap.SoulBootstrapApplication</mainClass>
<executable>true</executable>
</configuration>
</plugin>
<!-- maven install 跳过测试 等价于命令 mvn install -Dmaven.test.skip = true-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
</plugins>
</build>
</project>
注意:soul-bootstrap整合nacos注册,源码里面缺失archaius-core包,导致Caused by:
java.lang.ClassNotFoundException: com.netflix.config.CachedDynami,解决方式是添加archaius-
core包。
IDEA 中执行 SoulBootstrapApplication 启动服务网关。
2020-05-28 11:27:05.106 INFO 12032 --- [ main] o.s.s.c.ThreadPoolTaskScheduler : Initializing ExecutorService 'Nacso-Watch-Task-Scheduler'
2020-05-28 11:27:10.647 INFO 12032 --- [ main] o.s.cloud.commons.util.InetUtils : Cannot determine local hostname
2020-05-28 11:27:12.538 INFO 12032 --- [ main] o.s.b.a.e.web.EndpointLinksResolver : Exposing 2 endpoint(s) beneath base path '/actuator'
2020-05-28 11:27:14.274 INFO 12032 --- [ main] o.s.b.web.embedded.netty.NettyWebServer : Netty started on port(s): 9195
2020-05-28 11:27:16.026 INFO 12032 --- [ main] c.a.c.n.registry.NacosServiceRegistry : nacos registry, DEFAULT_GROUP soul-bootstrap 10.0.23.129:9195 register finished
2020-05-28 11:27:17.354 INFO 12032 --- [ main] o.d.s.b.SoulBootstrapApplication : Started SoulBootstrapApplication in 24.019 seconds (JVM running for 26.085)
2020-05-28 11:27:17.507 INFO 12032 --- [ main] o.d.s.web.cache.HttpLongPollSyncCache : request configs: [http://localhost:8082/configs/fetch?groupKeys=APP_AUTH&groupKeys=PLUGIN&groupKeys=RULE&groupKeys=SELECTOR&groupKeys=META_DATA]
2020-05-28 11:27:18.364 INFO 12032 --- [ main] o.d.s.web.cache.HttpLongPollSyncCache : get latest configs: [{"code":200,"message":"success","data":{"PLUGIN":{"md5":"1e130e26d2fac9f8cf6f20eb15091902","lastModifyTime":1590636368784,"data":[{"id":"1","name":"sign","config":null,"role":0,"enabled":false},{"id":"2","name":"waf","config":null,"role":0,"enabled":false},{"id":"3","name":"rewrite","config":null,"role":0,"enabled":false},{"id":"4","name":"rate_limiter","config":"{\"master\":\"mymaster\",\"mode\":\"Standalone\",\"url\":\"127.0.0.1:6379\",\"password\":\"\"}","role":0,"enabled":true},{"id":"5","name":"divide","config":null,"role":0,"enabled":false},{"id":"6","name":"dubbo","config":null,"role":0,"enabled":false},{"id":"7","name":"monitor","config":"{\"userName\":\"xiaoyu\",\"database\":\"databases\",\"url\":\"http://localhost:8086\",\"password\":\"test222\"}","role":0,"enabled":false},{"id":"8","name":"springCloud","config":null,"role":0,"enabled":true},{"id":"9","name":"hystrix","config":null,"role":0,"enabled":true}]},"META_DATA":{"md5":"5fc1db1cd050bbf63824565d3e3be6c9","lastModifyTime":1590636368886,"data":[{"id":"1265573822624882688","appName":"sping-soul-nacos","path":"/sc-user-service-api/user/create","rpcType":"springCloud","serviceName":"UserController","methodName":"createUser","parameterTypes":"com.hepu.springsoulnacos.controller.dto.UserCreateDTO","rpcExt":"","enabled":true},{"id":"1265573823186919424","appName":"sping-soul-nacos","path":"/sc-user-service-api/user/get","rpcType":"springCloud","serviceName":"UserController","methodName":"getUser","parameterTypes":"java.lang.Integer","rpcExt":"","enabled":true}]},"SELECTOR":{"md5":"cf20e00a5d06ecdab61fbe6b48fb732d","lastModifyTime":1590636368878,"data":[{"id":"1265573822687797248","pluginId":"8","pluginName":"springCloud","name":"/sc-user-service-api","matchMode":0,"type":1,"sort":1,"enabled":true,"loged":true,"continued":true,"handle":"sping-soul-nacos","conditionList":[{"paramType":"uri","operator":"match","paramName":"/","paramValue":"/sc-user-service-api/**"}]}]},"APP_AUTH":{"md5":"d751713988987e9331980363e24189ce","lastModifyTime":1590636368769,"data":[]},"RULE":{"md5":"d7c159a41db909091104bec8dc8bf243","lastModifyTime":1590636368866,"data":[{"id":"1265573822746517504","name":"/sc-user-service-api/user/create","pluginName":"springCloud","selectorId":"1265573822687797248","matchMode":0,"sort":1,"enabled":true,"loged":true,"handle":"{\"path\":\"/sc-user-service-api/user/create\",\"timeout\":3000}","conditionDataList":[{"paramType":"uri","operator":"=","paramName":"/","paramValue":"/sc-user-service-api/user/create"}]},{"id":"1265573823207890944","name":"/sc-user-service-api/user/get","pluginName":"springCloud","selectorId":"1265573822687797248","matchMode":0,"sort":1,"enabled":true,"loged":true,"handle":"{\"path\":\"/sc-user-service-api/user/get\",\"timeout\":3000}","conditionDataList":[{"paramType":"uri","operator":"=","paramName":"/","paramValue":"/sc-user-service-api/user/get"}]}]}}}]
2020-05-28 11:27:18.554 INFO 12032 --- [ main] o.d.soul.web.cache.HttpCacheHandler : clear all appAuth cache, old cache:{}
2020-05-28 11:27:22.083 INFO 12032 --- [oundedElastic-1] io.lettuce.core.EpollProvider : Starting without optional epoll library
2020-05-28 11:27:22.089 INFO 12032 --- [oundedElastic-1] io.lettuce.core.KqueueProvider : Starting without optional kqueue library
微服务网关 Soul搭建和集成SpringCloud Nacos案例(二)