mirror of
https://gitee.com/durcframework/SOP.git
synced 2025-08-12 07:02:14 +08:00
全面使用nacos,舍弃zookeeper
This commit is contained in:
@@ -62,7 +62,7 @@ SOP封装了开放平台大部分功能包括:签名验证、统一异常处
|
|||||||
|
|
||||||
## 工程说明
|
## 工程说明
|
||||||
|
|
||||||
> 运行环境:JDK8,Maven3,Zookeeper
|
> 运行环境:JDK8,Maven3,[Nacos](https://nacos.io/zh-cn/docs/what-is-nacos.html)
|
||||||
|
|
||||||
- doc:开发文档
|
- doc:开发文档
|
||||||
- sop-admin:后台管理
|
- sop-admin:后台管理
|
||||||
@@ -76,9 +76,9 @@ SOP封装了开放平台大部分功能包括:签名验证、统一异常处
|
|||||||
|
|
||||||
## 分支说明
|
## 分支说明
|
||||||
|
|
||||||
|
- master:发版分支
|
||||||
|
- spring-cloud-gateway:Spring Cloud Gateway作为网关
|
||||||
- develop:日常开发分支
|
- develop:日常开发分支
|
||||||
- registry-nacos:nacos作为注册中心
|
|
||||||
- SpringCloudGateway:SpringCloudGateway作为网关
|
|
||||||
|
|
||||||
## 相关文档
|
## 相关文档
|
||||||
|
|
||||||
|
@@ -1,22 +1,20 @@
|
|||||||
# 快速体验
|
# 快速体验
|
||||||
|
|
||||||
> 运行环境:JDK8,Maven3,Zookeeper,Mysql
|
> 运行环境:JDK8,Maven3,[Nacos](https://nacos.io/zh-cn/docs/what-is-nacos.html),Mysql
|
||||||
|
|
||||||
- 安装并启动zookeeper,[安装教程](http://zookeeper.apache.org/doc/r3.4.13/zookeeperStarted.html)
|
- 安装并启动Nacos,[安装教程](https://nacos.io/zh-cn/docs/quick-start.html)
|
||||||
- 执行Mysql脚本`sop.sql`
|
- 执行Mysql脚本`sop.sql`
|
||||||
- IDE安装lombok插件,然后打开项目(IDEA下可以打开根pom.xml,然后open as project)
|
- IDE安装lombok插件,然后打开项目(IDEA下可以打开根pom.xml,然后open as project)
|
||||||
- 启动注册中心,sop-registry(运行SopRegistryApplication.java)
|
- 启动注册中心,sop-registry(运行SopRegistryApplication.java)
|
||||||
- 启动网关:打开sop-gateway下的`application-dev.properties`
|
- 启动网关:打开sop-gateway下的`application-dev.properties`
|
||||||
1. 修改数据库`username/password`
|
1. 修改数据库`username/password`
|
||||||
2. 指定zookeeper地址,如果zookeeper安装在本机则不用改
|
2. 指定nacos地址,如果nacos安装在本机则不用改
|
||||||
3. 运行`SopGatewayApplication.java`
|
3. 运行`SopGatewayApplication.java`
|
||||||
- 启动微服务:打开sop-story-web下的`application-dev.properties`文件
|
- 启动微服务:打开sop-story-web下的`application-dev.properties`文件
|
||||||
1. 指定zookeeper地址,如果zookeeper安装在本机则不用改
|
1. 指定nacos地址,如果nacos安装在本机则不用改
|
||||||
2. 运行`SopStoryApplication.java`
|
2. 运行`SopStoryApplication.java`
|
||||||
- 找到sop-test,打开`AllInOneTest.java`进行接口调用测试
|
- 找到sop-test,打开`AllInOneTest.java`进行接口调用测试
|
||||||
|
|
||||||
确保注册中心先启动
|
|
||||||
|
|
||||||
## 使用admin
|
## 使用admin
|
||||||
|
|
||||||
- 找到`sop-admin/sop-admin-server`工程,打开sop-admin-server下的`application-dev.properties`,修改相关配置
|
- 找到`sop-admin/sop-admin-server`工程,打开sop-admin-server下的`application-dev.properties`,修改相关配置
|
||||||
|
@@ -39,10 +39,8 @@
|
|||||||
server.port=2222
|
server.port=2222
|
||||||
# 服务名称
|
# 服务名称
|
||||||
spring.application.name=story-service
|
spring.application.name=story-service
|
||||||
# eureka注册中心
|
# nacos注册中心
|
||||||
eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/
|
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
|
||||||
# zookeeper配置
|
|
||||||
spring.cloud.zookeeper.connect-string=localhost:2181
|
|
||||||
```
|
```
|
||||||
|
|
||||||
- 在springboot启动类上添加`@EnableDiscoveryClient`
|
- 在springboot启动类上添加`@EnableDiscoveryClient`
|
||||||
|
@@ -7,8 +7,8 @@
|
|||||||
|
|
||||||
SOP也是采用这种方式实现,大致步骤如下:
|
SOP也是采用这种方式实现,大致步骤如下:
|
||||||
|
|
||||||
- 每个服务注册到注册中心,在启动的时候把自己的路由信息上传到zookeeper,并且保证每一个接口都能对应到哪个服务。
|
- 每个服务注册到nacos
|
||||||
- 网关启动时同样注册到注册中心,获取zookeeper上的接口信息,保存到本地,并监听zookeeper上的接口信息,一旦接口信息有修改,网关这边能及时进行更新。
|
- 网关启动时同样注册到nacos,然后从各服务中拉取路由信息
|
||||||
- 网关收到客户端请求后,先进行签名校验,通过之后根据接口信息找到对应的服务,然后进行路由
|
- 网关收到客户端请求后,先进行签名校验,通过之后根据接口信息找到对应的服务,然后进行路由
|
||||||
- 网关对返回结果进行处理(或不处理),返回给客户端。
|
- 网关对返回结果进行处理(或不处理),返回给客户端。
|
||||||
|
|
||||||
@@ -16,10 +16,10 @@ SOP也是采用这种方式实现,大致步骤如下:
|
|||||||
|
|
||||||
在网关定义一个`Map<String, RouteInfo> routeMap = ...`,key为接口名+版本号。
|
在网关定义一个`Map<String, RouteInfo> routeMap = ...`,key为接口名+版本号。
|
||||||
|
|
||||||
网关启动时,从zookeeper中获取路由信息,并保存到routeMap中
|
网关启动时,从各微服务中获取路由信息,并保存到routeMap中
|
||||||
|
|
||||||
```java
|
```java
|
||||||
routeMap = buildFromZookeeper();
|
routeMap = requestFormServices();
|
||||||
```
|
```
|
||||||
|
|
||||||
接口请求进来后,根据`方法名+版本号`获取路由信息,然后进行路由转发。
|
接口请求进来后,根据`方法名+版本号`获取路由信息,然后进行路由转发。
|
||||||
@@ -33,7 +33,7 @@ RouteInfo routeInfo = routeMap.get(method + version);
|
|||||||
doRoute(routeInfo);
|
doRoute(routeInfo);
|
||||||
```
|
```
|
||||||
|
|
||||||
因为有多个服务把路由信息注册到zookeeper,我们要确保接口名唯一,即`method`全局唯一。
|
因为nacos需要拉取各个微服务的路由信息,接口名有可能会冲突,因此需要确保接口名唯一,即`method`全局唯一。
|
||||||
|
|
||||||
我们推荐接口名的命名规则应该是:`服务模块.业务模块.功能模块.行为`,如:
|
我们推荐接口名的命名规则应该是:`服务模块.业务模块.功能模块.行为`,如:
|
||||||
|
|
||||||
|
@@ -1,8 +1,6 @@
|
|||||||
# 使用SpringCloudGateway
|
# 使用SpringCloudGateway
|
||||||
|
|
||||||
SOP默认网关是使用Spring Cloud Zuul,您也可以切换成Spring Cloud Gateway,完整代码见`SpringCloudGateway`分支。
|
SOP默认网关是使用Spring Cloud Zuul,您也可以切换成Spring Cloud Gateway,完整代码见`spring-cloud-gateway`分支。
|
||||||
|
|
||||||
**注:**:SOP对Spring Cloud Gateway的支持目前处于beta阶段,推荐使用zuul。
|
|
||||||
|
|
||||||
步骤如下:
|
步骤如下:
|
||||||
|
|
||||||
|
@@ -1,90 +0,0 @@
|
|||||||
# nacos注册中心
|
|
||||||
|
|
||||||
使用nacos作为注册中心,源码在`registry-nacos`分支
|
|
||||||
|
|
||||||
这里演示如何将默认的eureka注册中心替换成nacos,步骤如下:
|
|
||||||
|
|
||||||
- 准备工作
|
|
||||||
|
|
||||||
1.安装nacos,前往[最新稳定版本](https://github.com/alibaba/nacos/releases),下载最新版nacos
|
|
||||||
|
|
||||||
2.启动nacos服务器,cd nacos/bin
|
|
||||||
|
|
||||||
Linux/Unix/Mac,启动命令(standalone代表着单机模式运行,非集群模式):
|
|
||||||
|
|
||||||
`sh startup.sh -m standalone`
|
|
||||||
|
|
||||||
Windows,启动命令:
|
|
||||||
|
|
||||||
`cmd startup.cmd`
|
|
||||||
|
|
||||||
或者双击startup.cmd运行文件。
|
|
||||||
|
|
||||||
更多访问:https://nacos.io/zh-cn/docs/quick-start.html
|
|
||||||
|
|
||||||
- 微服务端修改
|
|
||||||
|
|
||||||
1.修改微服务应用pom,打开`sop-example/sop-story/sop-story-web/pom.xml`,注释eureka服务发现依赖,添加nacos服务发现依赖
|
|
||||||
|
|
||||||
```xml
|
|
||||||
<!-- 注册中心【只能用一个,不用的注释掉】 -->
|
|
||||||
<!-- 使用eureka注册中心
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.cloud</groupId>
|
|
||||||
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
|
|
||||||
</dependency>
|
|
||||||
-->
|
|
||||||
|
|
||||||
<!-- 使用nacos注册中心
|
|
||||||
版本 0.2.x.RELEASE 对应的是 Spring Boot 2.x 版本,版本 0.1.x.RELEASE 对应的是 Spring Boot 1.x 版本。
|
|
||||||
https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-alibaba-nacos-discovery
|
|
||||||
-->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.cloud</groupId>
|
|
||||||
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
|
|
||||||
<version>0.2.2.RELEASE</version>
|
|
||||||
</dependency>
|
|
||||||
<!-- 注册中心end -->
|
|
||||||
```
|
|
||||||
|
|
||||||
2.yml文件新增nacos配置,并注释掉eureka相关配置
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
spring:
|
|
||||||
cloud:
|
|
||||||
# nacos注册中心,和eureka只能用一个
|
|
||||||
nacos:
|
|
||||||
discovery:
|
|
||||||
server-addr: 127.0.0.1:8848
|
|
||||||
```
|
|
||||||
|
|
||||||
- 网关修改
|
|
||||||
|
|
||||||
找到`sop-gateway`工程,步骤同上
|
|
||||||
|
|
||||||
- SOP-admin修改
|
|
||||||
|
|
||||||
|
|
||||||
修改yml文件,设置nacos服务器地址,`registry.name`填nacos
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
# 注册中心地址,根据实际情况改,这里只是参数,并不会去注册
|
|
||||||
registry:
|
|
||||||
eureka-server-addr: http://localhost:1111/eureka/
|
|
||||||
# nacos服务器地址
|
|
||||||
nacos-server-addr: 127.0.0.1:8848
|
|
||||||
# 使用eureka,填:eureka,使用nacos填:nacos
|
|
||||||
name: nacos
|
|
||||||
```
|
|
||||||
|
|
||||||
- website-server修改
|
|
||||||
|
|
||||||
步骤同`SOP-admin修改`
|
|
||||||
|
|
||||||
如果要改成consul注册中心,可参照以上步骤。
|
|
||||||
|
|
||||||
- 参考资料
|
|
||||||
|
|
||||||
1.[nacos介绍及安装](https://nacos.io/zh-cn/docs/quick-start.html)
|
|
||||||
|
|
||||||
2.[nacos spring cloud注册发现](https://nacos.io/zh-cn/docs/quick-start-spring-cloud.html)
|
|
@@ -1,112 +0,0 @@
|
|||||||
# 扩展其它注册中心
|
|
||||||
|
|
||||||
**注: nacos注册中心已经实现,本篇以nacos为例介绍如何扩展,如果要改成consul,可按照此方式进行修改**
|
|
||||||
|
|
||||||
SOP默认使用eureka注册中心,如果要换成nacos注册中心,步骤如下:
|
|
||||||
|
|
||||||
- 实现`com.gitee.sop.registryapi.service.RegistryService`接口
|
|
||||||
|
|
||||||
1.找到`SOP/sop-common/sop-registry-api`工程,在service.impl包下新建一个类,实现RegistryService接口
|
|
||||||
|
|
||||||
```java
|
|
||||||
public class RegistryServiceNacos implements RegistryService {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<ServiceInfo> listAllService(int pageNo, int pageSize) throws Exception {
|
|
||||||
// TODO: 返回服务实例
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onlineInstance(ServiceInstance serviceInstance) throws Exception {
|
|
||||||
// TODO: 实例上线
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void offlineInstance(ServiceInstance serviceInstance) throws Exception {
|
|
||||||
// TODO: 实例下线
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
2.在`com.gitee.sop.registryapi.config.BaseRegistryConfig`中新增
|
|
||||||
|
|
||||||
```java
|
|
||||||
/**
|
|
||||||
* 当配置了registry.name=nacos生效
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
@Bean
|
|
||||||
@ConditionalOnProperty(prefix = "registry", name = "name", havingValue = "nacos")
|
|
||||||
RegistryService registryServiceNacos() {
|
|
||||||
return new RegistryServiceNacos();
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
其中`@ConditionalOnProperty(prefix = "registry", name = "name", havingValue = "nacos")`
|
|
||||||
表示`application.properties`配置了`registry.name=nacos`参数才能生效,registry.name=nacos下文会讲到。
|
|
||||||
|
|
||||||
|
|
||||||
- 微服务端修改
|
|
||||||
|
|
||||||
1.修改微服务应用pom.xml,注释eureka服务发现依赖,添加nacos服务发现依赖
|
|
||||||
|
|
||||||
```xml
|
|
||||||
<!-- 注册中心【只能用一个,不用的注释掉】 -->
|
|
||||||
<!-- 使用eureka注册中心
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.cloud</groupId>
|
|
||||||
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
|
|
||||||
</dependency>
|
|
||||||
-->
|
|
||||||
|
|
||||||
<!-- 使用nacos注册中心
|
|
||||||
版本 0.2.x.RELEASE 对应的是 Spring Boot 2.x 版本,版本 0.1.x.RELEASE 对应的是 Spring Boot 1.x 版本。
|
|
||||||
https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-alibaba-nacos-discovery
|
|
||||||
-->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.cloud</groupId>
|
|
||||||
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
|
|
||||||
<version>0.2.2.RELEASE</version>
|
|
||||||
</dependency>
|
|
||||||
<!-- 注册中心end -->
|
|
||||||
```
|
|
||||||
|
|
||||||
2.yml文件新增nacos配置,并注释掉eureka相关配置
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
spring:
|
|
||||||
cloud:
|
|
||||||
# nacos注册中心,和eureka只能用一个
|
|
||||||
nacos:
|
|
||||||
discovery:
|
|
||||||
server-addr: 127.0.0.1:8848
|
|
||||||
```
|
|
||||||
|
|
||||||
- 网关修改
|
|
||||||
|
|
||||||
找到`sop-gateway`工程,步骤同上
|
|
||||||
|
|
||||||
- SOP-admin修改
|
|
||||||
|
|
||||||
|
|
||||||
修改yml文件,新增nacos服务器地址,`registry.name`填nacos
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
# 注册中心地址,根据实际情况改,这里只是参数,并不会去注册
|
|
||||||
registry:
|
|
||||||
# 使用eureka,填:eureka,使用nacos填:nacos
|
|
||||||
name: nacos
|
|
||||||
eureka-server-addr: http://localhost:1111/eureka/
|
|
||||||
nacos-server-addr: 127.0.0.1:8848
|
|
||||||
```
|
|
||||||
|
|
||||||
- website-server修改
|
|
||||||
|
|
||||||
步骤同`SOP-admin修改`
|
|
||||||
|
|
||||||
- 参考资料
|
|
||||||
|
|
||||||
1.[nacos介绍及安装](https://nacos.io/zh-cn/docs/quick-start.html)
|
|
||||||
|
|
||||||
2.[nacos spring cloud注册发现](https://nacos.io/zh-cn/docs/quick-start-spring-cloud.html)
|
|
@@ -1,25 +0,0 @@
|
|||||||
# 原理分析之路由存储
|
|
||||||
|
|
||||||
SOP将路由信息存到了zookeeper当中,服务在启动时,将自己的路由信息上传到zookeeper中。
|
|
||||||
网关监听存放路由的节点,动态更新到本地。
|
|
||||||
|
|
||||||
zookeeper存储路由的结构如下:
|
|
||||||
|
|
||||||
```xml
|
|
||||||
/com.gitee.sop.route 根节点
|
|
||||||
/serviceId 服务节点,名字为服务名
|
|
||||||
/route1 路由节点,名字为:name+version,存放路由信息
|
|
||||||
/route2
|
|
||||||
/...
|
|
||||||
```
|
|
||||||
|
|
||||||
服务启动时,创建`/serviceId`节点,然后遍历创建`/routeN`节点
|
|
||||||
|
|
||||||
同时,网关监听`服务节点`和`路由节点`,当有新服务加入时,网关会获取到新加入的路由节点信息,
|
|
||||||
同时路由节点下面的子节点也会被监听到。后续子节点的增删改都会被网关监听到,然后更新到本地。
|
|
||||||
|
|
||||||
服务上传路由相关代码在`com.gitee.sop.servercommon.manager.ServiceZookeeperApiMetaManager`类中
|
|
||||||
|
|
||||||
网关监听相关代码在`com.gitee.sop.gatewaycommon.manager.BaseRouteManager`中
|
|
||||||
|
|
||||||
|
|
@@ -19,16 +19,6 @@ OpenContext openContext = ServiceContext.getCurrentContext().getOpenContext();
|
|||||||
Story bizObject = openContext.getBizObject(Story.class);
|
Story bizObject = openContext.getBizObject(Story.class);
|
||||||
```
|
```
|
||||||
|
|
||||||
## Socket error occurred: `localhost/0:0:0:0:0:0:0:1:2181`: Connection refused
|
|
||||||
|
|
||||||
检查本地zookeeper有没启动,如果zookeeper在其他机器上,修改application-dev.yml
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
cloud:
|
|
||||||
zookeeper:
|
|
||||||
connect-string: ip:2181
|
|
||||||
```
|
|
||||||
|
|
||||||
## 如何关闭签名验证
|
## 如何关闭签名验证
|
||||||
|
|
||||||
- 针对某一个接口关闭签名验证
|
- 针对某一个接口关闭签名验证
|
||||||
|
@@ -21,8 +21,6 @@
|
|||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||||
<java.version>1.8</java.version>
|
<java.version>1.8</java.version>
|
||||||
<zookeeper.version>3.4.12</zookeeper.version>
|
|
||||||
<curator-recipes.version>4.0.1</curator-recipes.version>
|
|
||||||
<okhttp.version>3.11.0</okhttp.version>
|
<okhttp.version>3.11.0</okhttp.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
@@ -30,12 +28,12 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.alibaba.boot</groupId>
|
<groupId>com.alibaba.boot</groupId>
|
||||||
<artifactId>nacos-config-spring-boot-starter</artifactId>
|
<artifactId>nacos-config-spring-boot-starter</artifactId>
|
||||||
<version>0.2.2</version>
|
<version>0.2.3</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.alibaba.boot</groupId>
|
<groupId>com.alibaba.boot</groupId>
|
||||||
<artifactId>nacos-discovery-spring-boot-starter</artifactId>
|
<artifactId>nacos-discovery-spring-boot-starter</artifactId>
|
||||||
<version>0.2.2</version>
|
<version>0.2.3</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
|
@@ -292,10 +292,10 @@ public class IsvApi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
routePermissionService.sendIsvRolePermissionToZookeeper(isvInfo.getAppKey(), roleCodeList);
|
routePermissionService.sendIsvRolePermissionMsg(isvInfo.getAppKey(), roleCodeList);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("保存到zookeeper中失败,isvInfo:{}, roleCodeList:{}", isvInfo, roleCodeList);
|
log.error("同步角色失败,isvInfo:{}, roleCodeList:{}", isvInfo, roleCodeList);
|
||||||
throw new BizException("同步zookeeper失败,请查看网关日志");
|
throw new BizException("同步角色失败,请查看网关日志");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -4,7 +4,6 @@ import com.gitee.easyopen.annotation.Api;
|
|||||||
import com.gitee.easyopen.annotation.ApiService;
|
import com.gitee.easyopen.annotation.ApiService;
|
||||||
import com.gitee.easyopen.doc.annotation.ApiDoc;
|
import com.gitee.easyopen.doc.annotation.ApiDoc;
|
||||||
import com.gitee.easyopen.doc.annotation.ApiDocMethod;
|
import com.gitee.easyopen.doc.annotation.ApiDocMethod;
|
||||||
import com.gitee.easyopen.util.CopyUtil;
|
|
||||||
import com.gitee.sop.adminserver.api.isv.result.RoleVO;
|
import com.gitee.sop.adminserver.api.isv.result.RoleVO;
|
||||||
import com.gitee.sop.adminserver.api.service.param.RouteAddParam;
|
import com.gitee.sop.adminserver.api.service.param.RouteAddParam;
|
||||||
import com.gitee.sop.adminserver.api.service.param.RouteDeleteParam;
|
import com.gitee.sop.adminserver.api.service.param.RouteDeleteParam;
|
||||||
@@ -95,46 +94,19 @@ public class RouteApi {
|
|||||||
@Api(name = "route.add")
|
@Api(name = "route.add")
|
||||||
@ApiDocMethod(description = "新增路由")
|
@ApiDocMethod(description = "新增路由")
|
||||||
void addRoute(RouteAddParam param) {
|
void addRoute(RouteAddParam param) {
|
||||||
// TODO:新增路由
|
// TODO: 新增路由
|
||||||
String id = param.getName() + param.getVersion();
|
|
||||||
// String routePath = ZookeeperContext.buildRoutePath(param.getServiceId(), id);
|
|
||||||
GatewayRouteDefinition routeDefinition = new GatewayRouteDefinition();
|
|
||||||
CopyUtil.copyPropertiesIgnoreNull(param, routeDefinition);
|
|
||||||
routeDefinition.setId(id);
|
|
||||||
routeDefinition.setCustom(1);
|
|
||||||
// try {
|
|
||||||
// ZookeeperContext.addPath(routePath, JSON.toJSONString(routeDefinition));
|
|
||||||
// } catch (ZookeeperPathExistException e) {
|
|
||||||
// throw new BizException("路由已存在");
|
|
||||||
// }
|
|
||||||
this.updateRouteConfig(routeDefinition);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Api(name = "route.update")
|
@Api(name = "route.update")
|
||||||
@ApiDocMethod(description = "修改路由")
|
@ApiDocMethod(description = "修改路由")
|
||||||
void updateRoute(RouteUpdateParam param) {
|
void updateRoute(RouteUpdateParam param) {
|
||||||
// TODO:修改路由
|
// TODO: 修改路由
|
||||||
// String routePath = ZookeeperContext.buildRoutePath(param.getServiceId(), param.getId());
|
|
||||||
// GatewayRouteDefinition routeDefinition = this.getGatewayRouteDefinition(routePath);
|
|
||||||
// CopyUtil.copyPropertiesIgnoreNull(param, routeDefinition);
|
|
||||||
// try {
|
|
||||||
// ZookeeperContext.updatePathData(routePath, JSON.toJSONString(routeDefinition));
|
|
||||||
// } catch (ZookeeperPathNotExistException e) {
|
|
||||||
// throw new BizException("路由不存在");
|
|
||||||
// }
|
|
||||||
// this.updateRouteConfig(routeDefinition);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Api(name = "route.del")
|
@Api(name = "route.del")
|
||||||
@ApiDocMethod(description = "删除路由")
|
@ApiDocMethod(description = "删除路由")
|
||||||
void delRoute(RouteDeleteParam param) {
|
void delRoute(RouteDeleteParam param) {
|
||||||
// TODO:删除路由
|
// TODO: 删除路由
|
||||||
/*String routePath = ZookeeperContext.buildRoutePath(param.getServiceId(), param.getId());
|
|
||||||
GatewayRouteDefinition routeDefinition = this.getGatewayRouteDefinition(routePath);
|
|
||||||
if (!BooleanUtils.toBoolean(routeDefinition.getCustom())) {
|
|
||||||
throw new BizException("非自定义路由,无法删除");
|
|
||||||
}
|
|
||||||
ZookeeperContext.deletePathDeep(routePath);*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -1,19 +0,0 @@
|
|||||||
package com.gitee.sop.adminserver.bean;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author tanghc
|
|
||||||
*/
|
|
||||||
public class SopAdminConstants {
|
|
||||||
/**
|
|
||||||
* zookeeper存放接口路由信息的根目录
|
|
||||||
*/
|
|
||||||
public static final String SOP_SERVICE_ROUTE_PATH = "/com.gitee.sop.route";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 消息监听路径
|
|
||||||
*/
|
|
||||||
public static final String SOP_MSG_CHANNEL_PATH = "/com.gitee.sop.channel";
|
|
||||||
|
|
||||||
public static final String RELOAD_ROUTE_PERMISSION_PATH = "/com.gitee.sop.route.permission.reload";
|
|
||||||
|
|
||||||
}
|
|
@@ -58,12 +58,12 @@ public class RoutePermissionService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 推送isv路由权限到zookeeper
|
* 推送isv路由权限
|
||||||
*
|
*
|
||||||
* @param appKey
|
* @param appKey
|
||||||
* @param roleCodeList
|
* @param roleCodeList
|
||||||
*/
|
*/
|
||||||
public void sendIsvRolePermissionToZookeeper(String appKey, List<String> roleCodeList) throws Exception {
|
public void sendIsvRolePermissionMsg(String appKey, List<String> roleCodeList) throws Exception {
|
||||||
Collections.sort(roleCodeList);
|
Collections.sort(roleCodeList);
|
||||||
List<String> routeIdList = this.getRouteIdList(roleCodeList);
|
List<String> routeIdList = this.getRouteIdList(roleCodeList);
|
||||||
String roleCodeListMd5 = DigestUtils.md5Hex(JSON.toJSONString(routeIdList));
|
String roleCodeListMd5 = DigestUtils.md5Hex(JSON.toJSONString(routeIdList));
|
||||||
@@ -95,7 +95,7 @@ public class RoutePermissionService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 推送所有路由权限到zookeeper
|
* 推送所有路由权限
|
||||||
*/
|
*/
|
||||||
public void sendRoutePermissionReloadMsg(RoutePermissionParam oldRoutePermission) throws Exception {
|
public void sendRoutePermissionReloadMsg(RoutePermissionParam oldRoutePermission) throws Exception {
|
||||||
IsvRoutePermission isvRoutePermission = new IsvRoutePermission();
|
IsvRoutePermission isvRoutePermission = new IsvRoutePermission();
|
||||||
|
@@ -42,17 +42,6 @@ public class SopConstants {
|
|||||||
|
|
||||||
public static final int BIZ_ERROR_STATUS = 4000;
|
public static final int BIZ_ERROR_STATUS = 4000;
|
||||||
|
|
||||||
/**
|
|
||||||
* zookeeper存放接口路由信息的根目录
|
|
||||||
*/
|
|
||||||
public static final String SOP_SERVICE_ROUTE_PATH = "/com.gitee.sop.route";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 消息监听路径
|
|
||||||
*/
|
|
||||||
public static final String SOP_MSG_CHANNEL_PATH = "/com.gitee.sop.channel";
|
|
||||||
|
|
||||||
|
|
||||||
public static final String UNKNOWN_SERVICE= "_sop_unknown_service_";
|
public static final String UNKNOWN_SERVICE= "_sop_unknown_service_";
|
||||||
public static final String UNKNOWN_METHOD = "_sop_unknown_method_";
|
public static final String UNKNOWN_METHOD = "_sop_unknown_method_";
|
||||||
public static final String UNKNOWN_VERSION = "_sop_unknown_version_";
|
public static final String UNKNOWN_VERSION = "_sop_unknown_version_";
|
||||||
|
@@ -1,7 +1,5 @@
|
|||||||
package com.gitee.sop.servercommon.bean;
|
package com.gitee.sop.servercommon.bean;
|
||||||
|
|
||||||
import com.gitee.sop.servercommon.configuration.DefaultGlobalExceptionHandler;
|
|
||||||
import com.gitee.sop.servercommon.configuration.GlobalExceptionHandler;
|
|
||||||
import com.gitee.sop.servercommon.param.ApiArgumentResolver;
|
import com.gitee.sop.servercommon.param.ApiArgumentResolver;
|
||||||
import com.gitee.sop.servercommon.param.SopHandlerMethodArgumentResolver;
|
import com.gitee.sop.servercommon.param.SopHandlerMethodArgumentResolver;
|
||||||
import com.gitee.sop.servercommon.result.DefaultServiceResultBuilder;
|
import com.gitee.sop.servercommon.result.DefaultServiceResultBuilder;
|
||||||
@@ -45,11 +43,6 @@ public class ServiceConfig {
|
|||||||
*/
|
*/
|
||||||
private ServiceResultBuilder serviceResultBuilder = new DefaultServiceResultBuilder();
|
private ServiceResultBuilder serviceResultBuilder = new DefaultServiceResultBuilder();
|
||||||
|
|
||||||
/**
|
|
||||||
* 全局异常处理
|
|
||||||
*/
|
|
||||||
private GlobalExceptionHandler globalExceptionHandler = new DefaultGlobalExceptionHandler();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 默认版本号
|
* 默认版本号
|
||||||
*/
|
*/
|
||||||
|
@@ -1,16 +0,0 @@
|
|||||||
package com.gitee.sop.servercommon.bean;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author tanghc
|
|
||||||
*/
|
|
||||||
public class ServiceConstants {
|
|
||||||
/**
|
|
||||||
* zookeeper存放接口路由信息的根目录
|
|
||||||
*/
|
|
||||||
public static final String SOP_SERVICE_ROUTE_PATH = "/com.gitee.sop.route";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 服务临时节点
|
|
||||||
*/
|
|
||||||
public static final String SOP_SERVICE_TEMP_PATH = "/com.gitee.sop.service.tmp";
|
|
||||||
}
|
|
@@ -8,6 +8,7 @@ import com.gitee.sop.servercommon.message.ServiceErrorFactory;
|
|||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.boot.ApplicationArguments;
|
import org.springframework.boot.ApplicationArguments;
|
||||||
import org.springframework.boot.ApplicationRunner;
|
import org.springframework.boot.ApplicationRunner;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.http.converter.HttpMessageConverter;
|
import org.springframework.http.converter.HttpMessageConverter;
|
||||||
import org.springframework.http.converter.StringHttpMessageConverter;
|
import org.springframework.http.converter.StringHttpMessageConverter;
|
||||||
@@ -70,12 +71,20 @@ public class BaseServiceConfiguration extends WebMvcConfigurationSupport
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
|
@ConditionalOnMissingBean
|
||||||
GlobalExceptionHandler globalExceptionHandler() {
|
GlobalExceptionHandler globalExceptionHandler() {
|
||||||
return ServiceConfig.getInstance().getGlobalExceptionHandler();
|
return new GlobalExceptionHandler();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
ServiceRouteController serviceRouteController() {
|
@ConditionalOnMissingBean
|
||||||
|
ErrorController errorController() {
|
||||||
|
return new ErrorController();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnMissingBean
|
||||||
|
ServiceRouteController serviceRouteInfoHandler() {
|
||||||
return new ServiceRouteController();
|
return new ServiceRouteController();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,92 +0,0 @@
|
|||||||
package com.gitee.sop.servercommon.configuration;
|
|
||||||
|
|
||||||
import com.gitee.sop.servercommon.bean.ServiceConfig;
|
|
||||||
import com.gitee.sop.servercommon.exception.ServiceException;
|
|
||||||
import com.gitee.sop.servercommon.result.ServiceResultBuilder;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.springframework.web.bind.annotation.ControllerAdvice;
|
|
||||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.ResponseBody;
|
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 全局异常处理
|
|
||||||
* @author tanghc
|
|
||||||
*/
|
|
||||||
@ControllerAdvice
|
|
||||||
@Slf4j
|
|
||||||
public class DefaultGlobalExceptionHandler implements GlobalExceptionHandler {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 与网关约定好的状态码,表示业务出错
|
|
||||||
*/
|
|
||||||
public static final int BIZ_ERROR_CODE = 4000;
|
|
||||||
/**
|
|
||||||
* 系统错误
|
|
||||||
*/
|
|
||||||
public static final int SYSTEM_ERROR_CODE = 5050;
|
|
||||||
|
|
||||||
public static final String X_SERVICE_ERROR_CODE = "x-service-error-code";
|
|
||||||
|
|
||||||
@RequestMapping("/error")
|
|
||||||
@ResponseBody
|
|
||||||
public Object error(HttpServletRequest request, HttpServletResponse response) {
|
|
||||||
ServiceResultBuilder serviceResultBuilder = ServiceConfig.getInstance().getServiceResultBuilder();
|
|
||||||
return serviceResultBuilder.buildError(request, response, new ServiceException("系统繁忙"));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 捕获手动抛出的异常
|
|
||||||
* @param request
|
|
||||||
* @param response
|
|
||||||
* @param exception
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
@ExceptionHandler(ServiceException.class)
|
|
||||||
@ResponseBody
|
|
||||||
public Object serviceExceptionHandler(HttpServletRequest request, HttpServletResponse response, Exception exception) {
|
|
||||||
response.addHeader(X_SERVICE_ERROR_CODE, String.valueOf(BIZ_ERROR_CODE));
|
|
||||||
return this.processError(request, response, exception);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 捕获未知异常
|
|
||||||
* @param request
|
|
||||||
* @param response
|
|
||||||
* @param exception
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
@ExceptionHandler(Exception.class)
|
|
||||||
@ResponseBody
|
|
||||||
public Object exceptionHandler(HttpServletRequest request, HttpServletResponse response, Exception exception) {
|
|
||||||
response.addHeader(X_SERVICE_ERROR_CODE, String.valueOf(SYSTEM_ERROR_CODE));
|
|
||||||
log.error("系统错误", exception);
|
|
||||||
StringBuilder msg = new StringBuilder();
|
|
||||||
msg.append(exception.getMessage());
|
|
||||||
StackTraceElement[] stackTrace = exception.getStackTrace();
|
|
||||||
// 取5行错误内容
|
|
||||||
int lineCount = 5;
|
|
||||||
for (int i = 0; i < stackTrace.length && i < lineCount ; i++) {
|
|
||||||
StackTraceElement stackTraceElement = stackTrace[i];
|
|
||||||
msg.append("<br> at ").append(stackTraceElement.toString());
|
|
||||||
}
|
|
||||||
response.setHeader("x-service-error-message", msg.toString());
|
|
||||||
return this.processError(request, response, new ServiceException("系统繁忙"));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 处理异常
|
|
||||||
*
|
|
||||||
* @param request
|
|
||||||
* @param response
|
|
||||||
* @param exception
|
|
||||||
* @return 返回最终结果
|
|
||||||
*/
|
|
||||||
protected Object processError(HttpServletRequest request, HttpServletResponse response, Exception exception) {
|
|
||||||
ServiceResultBuilder serviceResultBuilder = ServiceConfig.getInstance().getServiceResultBuilder();
|
|
||||||
return serviceResultBuilder.buildError(request, response, exception);
|
|
||||||
}
|
|
||||||
}
|
|
@@ -0,0 +1,27 @@
|
|||||||
|
package com.gitee.sop.servercommon.configuration;
|
||||||
|
|
||||||
|
import com.gitee.sop.servercommon.bean.ServiceConfig;
|
||||||
|
import com.gitee.sop.servercommon.exception.ServiceException;
|
||||||
|
import com.gitee.sop.servercommon.result.ServiceResultBuilder;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author tanghc
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
public class ErrorController {
|
||||||
|
|
||||||
|
@RequestMapping("/error")
|
||||||
|
public Object error(HttpServletRequest request, HttpServletResponse response) {
|
||||||
|
return getResult(request, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Object getResult(HttpServletRequest request, HttpServletResponse response) {
|
||||||
|
ServiceResultBuilder serviceResultBuilder = ServiceConfig.getInstance().getServiceResultBuilder();
|
||||||
|
return serviceResultBuilder.buildError(request, response, new ServiceException("系统繁忙"));
|
||||||
|
}
|
||||||
|
}
|
@@ -1,7 +1,92 @@
|
|||||||
package com.gitee.sop.servercommon.configuration;
|
package com.gitee.sop.servercommon.configuration;
|
||||||
|
|
||||||
|
import com.gitee.sop.servercommon.bean.ServiceConfig;
|
||||||
|
import com.gitee.sop.servercommon.exception.ServiceException;
|
||||||
|
import com.gitee.sop.servercommon.result.ServiceResultBuilder;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.web.bind.annotation.ControllerAdvice;
|
||||||
|
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* 全局异常处理
|
||||||
* @author tanghc
|
* @author tanghc
|
||||||
*/
|
*/
|
||||||
public interface GlobalExceptionHandler {
|
@ControllerAdvice
|
||||||
|
@Slf4j
|
||||||
|
public class GlobalExceptionHandler {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 与网关约定好的状态码,表示业务出错
|
||||||
|
*/
|
||||||
|
public static final int BIZ_ERROR_CODE = 4000;
|
||||||
|
/**
|
||||||
|
* 系统错误
|
||||||
|
*/
|
||||||
|
public static final int SYSTEM_ERROR_CODE = 5050;
|
||||||
|
|
||||||
|
public static final String X_SERVICE_ERROR_CODE = "x-service-error-code";
|
||||||
|
|
||||||
|
@RequestMapping("/error")
|
||||||
|
@ResponseBody
|
||||||
|
public Object error(HttpServletRequest request, HttpServletResponse response) {
|
||||||
|
ServiceResultBuilder serviceResultBuilder = ServiceConfig.getInstance().getServiceResultBuilder();
|
||||||
|
return serviceResultBuilder.buildError(request, response, new ServiceException("系统繁忙"));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 捕获手动抛出的异常
|
||||||
|
* @param request
|
||||||
|
* @param response
|
||||||
|
* @param exception
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@ExceptionHandler(ServiceException.class)
|
||||||
|
@ResponseBody
|
||||||
|
public Object serviceExceptionHandler(HttpServletRequest request, HttpServletResponse response, Exception exception) {
|
||||||
|
response.addHeader(X_SERVICE_ERROR_CODE, String.valueOf(BIZ_ERROR_CODE));
|
||||||
|
return this.processError(request, response, exception);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 捕获未知异常
|
||||||
|
* @param request
|
||||||
|
* @param response
|
||||||
|
* @param exception
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@ExceptionHandler(Exception.class)
|
||||||
|
@ResponseBody
|
||||||
|
public Object exceptionHandler(HttpServletRequest request, HttpServletResponse response, Exception exception) {
|
||||||
|
response.addHeader(X_SERVICE_ERROR_CODE, String.valueOf(SYSTEM_ERROR_CODE));
|
||||||
|
log.error("系统错误", exception);
|
||||||
|
StringBuilder msg = new StringBuilder();
|
||||||
|
msg.append(exception.getMessage());
|
||||||
|
StackTraceElement[] stackTrace = exception.getStackTrace();
|
||||||
|
// 取5行错误内容
|
||||||
|
int lineCount = 5;
|
||||||
|
for (int i = 0; i < stackTrace.length && i < lineCount ; i++) {
|
||||||
|
StackTraceElement stackTraceElement = stackTrace[i];
|
||||||
|
msg.append("<br> at ").append(stackTraceElement.toString());
|
||||||
|
}
|
||||||
|
response.setHeader("x-service-error-message", msg.toString());
|
||||||
|
return this.processError(request, response, new ServiceException("系统繁忙"));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理异常
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @param response
|
||||||
|
* @param exception
|
||||||
|
* @return 返回最终结果
|
||||||
|
*/
|
||||||
|
protected Object processError(HttpServletRequest request, HttpServletResponse response, Exception exception) {
|
||||||
|
ServiceResultBuilder serviceResultBuilder = ServiceConfig.getInstance().getServiceResultBuilder();
|
||||||
|
return serviceResultBuilder.buildError(request, response, exception);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -37,7 +37,7 @@ public class SpringMvcServiceConfiguration {
|
|||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
GlobalExceptionHandler globalExceptionHandler() {
|
GlobalExceptionHandler globalExceptionHandler() {
|
||||||
return ServiceConfig.getInstance().getGlobalExceptionHandler();
|
return new GlobalExceptionHandler();
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostConstruct
|
@PostConstruct
|
||||||
|
@@ -3,6 +3,7 @@ package com.gitee.sop.servercommon.manager;
|
|||||||
import com.gitee.sop.servercommon.bean.ServiceApiInfo;
|
import com.gitee.sop.servercommon.bean.ServiceApiInfo;
|
||||||
import com.gitee.sop.servercommon.route.ServiceRouteInfo;
|
import com.gitee.sop.servercommon.route.ServiceRouteInfo;
|
||||||
import com.gitee.sop.servercommon.util.OpenUtil;
|
import com.gitee.sop.servercommon.util.OpenUtil;
|
||||||
|
import lombok.Getter;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.core.env.Environment;
|
import org.springframework.core.env.Environment;
|
||||||
@@ -17,6 +18,7 @@ import javax.servlet.http.HttpServletResponse;
|
|||||||
* @author tanghc
|
* @author tanghc
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
@Getter
|
||||||
@RestController
|
@RestController
|
||||||
public class ServiceRouteController {
|
public class ServiceRouteController {
|
||||||
|
|
||||||
@@ -35,6 +37,10 @@ public class ServiceRouteController {
|
|||||||
log.error("签名验证失败, params:{}", request.getQueryString());
|
log.error("签名验证失败, params:{}", request.getQueryString());
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
return getServiceRouteInfo(request, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected ServiceRouteInfo getServiceRouteInfo(HttpServletRequest request, HttpServletResponse response) {
|
||||||
String serviceId = environment.getProperty("spring.application.name");
|
String serviceId = environment.getProperty("spring.application.name");
|
||||||
ApiMetaBuilder apiMetaBuilder = new ApiMetaBuilder();
|
ApiMetaBuilder apiMetaBuilder = new ApiMetaBuilder();
|
||||||
ServiceApiInfo serviceApiInfo = apiMetaBuilder.getServiceApiInfo(serviceId, requestMappingHandlerMapping);
|
ServiceApiInfo serviceApiInfo = apiMetaBuilder.getServiceApiInfo(serviceId, requestMappingHandlerMapping);
|
||||||
@@ -42,5 +48,4 @@ public class ServiceRouteController {
|
|||||||
return serviceRouteInfoBuilder.build(serviceApiInfo);
|
return serviceRouteInfoBuilder.build(serviceApiInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,9 @@
|
|||||||
|
package com.gitee.sop.servercommon.manager;
|
||||||
|
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author tanghc
|
||||||
|
*/
|
||||||
|
public interface ServiceRouteInfoHandler {
|
||||||
|
}
|
@@ -1,7 +1,6 @@
|
|||||||
package com.gitee.sop.servercommon.route;
|
package com.gitee.sop.servercommon.route;
|
||||||
|
|
||||||
import com.alibaba.fastjson.annotation.JSONField;
|
import com.alibaba.fastjson.annotation.JSONField;
|
||||||
import com.gitee.sop.servercommon.bean.ServiceConstants;
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
@@ -12,10 +11,10 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
public class ServiceRouteInfo {
|
public class ServiceRouteInfo {
|
||||||
private static final String SOP_SERVICE_ROUTE_PATH = ServiceConstants.SOP_SERVICE_ROUTE_PATH;
|
|
||||||
private static final String SOP_SERVICE_TEMP_PATH = ServiceConstants.SOP_SERVICE_TEMP_PATH;
|
|
||||||
|
|
||||||
/** 服务名称,对应spring.application.name */
|
/**
|
||||||
|
* 服务名称,对应spring.application.name
|
||||||
|
*/
|
||||||
private String serviceId;
|
private String serviceId;
|
||||||
|
|
||||||
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
|
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
|
||||||
@@ -26,36 +25,12 @@ public class ServiceRouteInfo {
|
|||||||
|
|
||||||
private String description;
|
private String description;
|
||||||
|
|
||||||
/** 路由信息md5,md5(sort(routeIdList)) */
|
/**
|
||||||
|
* 路由信息md5,md5(sort(routeIdList))
|
||||||
|
*/
|
||||||
private String md5;
|
private String md5;
|
||||||
|
|
||||||
@JSONField(serialize = false)
|
@JSONField(serialize = false)
|
||||||
private List<GatewayRouteDefinition> routeDefinitionList;
|
private List<GatewayRouteDefinition> routeDefinitionList;
|
||||||
|
|
||||||
/**
|
|
||||||
* 返回zookeeper路径
|
|
||||||
* @return 返回zookeeper路径
|
|
||||||
*/
|
|
||||||
@JSONField(serialize = false)
|
|
||||||
public String getZookeeperPath() {
|
|
||||||
return SOP_SERVICE_ROUTE_PATH + '/' + serviceId;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 返回zookeeper路径
|
|
||||||
* @return 返回zookeeper路径
|
|
||||||
*/
|
|
||||||
@JSONField(serialize = false)
|
|
||||||
public String getZookeeperTempServiceIdPath() {
|
|
||||||
return SOP_SERVICE_TEMP_PATH + '/' + serviceId;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 返回zookeeper路径
|
|
||||||
* @return 返回zookeeper路径
|
|
||||||
*/
|
|
||||||
@JSONField(serialize = false)
|
|
||||||
public String getZookeeperTempServiceIdChildPath() {
|
|
||||||
return getZookeeperTempServiceIdPath() + "/" + serviceId;
|
|
||||||
}
|
|
||||||
}
|
}
|
@@ -1,17 +1,13 @@
|
|||||||
server.port=3333
|
server.port=3333
|
||||||
spring.application.name=book-service
|
spring.application.name=book-service
|
||||||
spring.application.description=book服务
|
|
||||||
|
|
||||||
# nacos注册中心
|
# nacos注册中心
|
||||||
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
|
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
|
||||||
|
|
||||||
# zookeeper配置
|
|
||||||
spring.cloud.zookeeper.connect-string=localhost:2181
|
|
||||||
|
|
||||||
# zipkin服务跟踪
|
# zipkin服务跟踪
|
||||||
spring.zipkin.base-url=http://127.0.0.1:9411/
|
#spring.zipkin.base-url=http://127.0.0.1:9411/
|
||||||
# 设置sleuth收集信息的比率,默认0.1,最大是1,数字越大越耗性能
|
## 设置sleuth收集信息的比率,默认0.1,最大是1,数字越大越耗性能
|
||||||
spring.sleuth.sampler.probability=1
|
#spring.sleuth.sampler.probability=1
|
||||||
# dubbo使用zipkin过滤器
|
## dubbo使用zipkin过滤器
|
||||||
dubbo.provider.filter=tracing
|
#dubbo.provider.filter=tracing
|
||||||
dubbo.consumer.filter=tracing
|
#dubbo.consumer.filter=tracing
|
||||||
|
@@ -1,13 +1,9 @@
|
|||||||
server.port=2222
|
server.port=2222
|
||||||
spring.application.name=story-service
|
spring.application.name=story-service
|
||||||
spring.application.description=story服务
|
|
||||||
|
|
||||||
# nacos注册中心
|
# nacos注册中心
|
||||||
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
|
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
|
||||||
|
|
||||||
# zookeeper配置
|
|
||||||
spring.cloud.zookeeper.connect-string=localhost:2181
|
|
||||||
|
|
||||||
# dubbo配置
|
# dubbo配置
|
||||||
dubbo.protocol.name=dubbo
|
dubbo.protocol.name=dubbo
|
||||||
dubbo.protocol.port=12345
|
dubbo.protocol.port=12345
|
||||||
|
@@ -100,31 +100,6 @@ public class DbEnvGrayManager extends DefaultEnvGrayManager {
|
|||||||
|
|
||||||
@PostConstruct
|
@PostConstruct
|
||||||
protected void after() throws Exception {
|
protected void after() throws Exception {
|
||||||
/*ZookeeperContext.setEnvironment(environment);
|
|
||||||
String isvChannelPath = ZookeeperContext.getServiceGrayChannelPath();
|
|
||||||
ZookeeperContext.listenPath(isvChannelPath, nodeCache -> {
|
|
||||||
String nodeData = new String(nodeCache.getCurrentData().getData());
|
|
||||||
ChannelMsg channelMsg = JSON.parseObject(nodeData, ChannelMsg.class);
|
|
||||||
String data = channelMsg.getData();
|
|
||||||
ServiceGrayDefinition userKeyDefinition = JSON.parseObject(data, ServiceGrayDefinition.class);
|
|
||||||
String serviceId = userKeyDefinition.getServiceId();
|
|
||||||
switch (channelMsg.getOperation()) {
|
|
||||||
case "set":
|
|
||||||
ConfigGray configGray = configGrayMapper.getByColumn("service_id", serviceId);
|
|
||||||
this.setServiceGrayConfig(configGray);
|
|
||||||
break;
|
|
||||||
case "open":
|
|
||||||
openGray(userKeyDefinition.getInstanceId(), serviceId);
|
|
||||||
break;
|
|
||||||
case "close":
|
|
||||||
closeGray(userKeyDefinition.getInstanceId());
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
|
|
||||||
}
|
|
||||||
});*/
|
|
||||||
|
|
||||||
// nacos
|
|
||||||
ConfigService configService = nacosConfigProperties.configServiceInstance();
|
ConfigService configService = nacosConfigProperties.configServiceInstance();
|
||||||
configService.addListener(NacosConfigs.DATA_ID_GRAY, NacosConfigs.GROUP_CHANNEL, new AbstractListener() {
|
configService.addListener(NacosConfigs.DATA_ID_GRAY, NacosConfigs.GROUP_CHANNEL, new AbstractListener() {
|
||||||
@Override
|
@Override
|
||||||
|
@@ -41,26 +41,6 @@ public class DbIPBlacklistManager extends DefaultIPBlacklistManager {
|
|||||||
|
|
||||||
@PostConstruct
|
@PostConstruct
|
||||||
protected void after() throws Exception {
|
protected void after() throws Exception {
|
||||||
/*ZookeeperContext.setEnvironment(environment);
|
|
||||||
String path = ZookeeperContext.getIpBlacklistChannelPath();
|
|
||||||
ZookeeperContext.listenPath(path, nodeCache -> {
|
|
||||||
String nodeData = new String(nodeCache.getCurrentData().getData());
|
|
||||||
ChannelMsg channelMsg = JSON.parseObject(nodeData, ChannelMsg.class);
|
|
||||||
final IPDto ipDto = JSON.parseObject(channelMsg.getData(), IPDto.class);
|
|
||||||
String ip = ipDto.getIp();
|
|
||||||
switch (channelMsg.getOperation()) {
|
|
||||||
case "add":
|
|
||||||
log.info("添加IP黑名单,ip:{}", ip);
|
|
||||||
add(ip);
|
|
||||||
break;
|
|
||||||
case "delete":
|
|
||||||
log.info("移除IP黑名单,ip:{}", ip);
|
|
||||||
remove(ip);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
}
|
|
||||||
});*/
|
|
||||||
// nacos
|
|
||||||
ConfigService configService = nacosConfigProperties.configServiceInstance();
|
ConfigService configService = nacosConfigProperties.configServiceInstance();
|
||||||
configService.addListener(NacosConfigs.DATA_ID_IP_BLACKLIST, NacosConfigs.GROUP_CHANNEL, new AbstractListener() {
|
configService.addListener(NacosConfigs.DATA_ID_IP_BLACKLIST, NacosConfigs.GROUP_CHANNEL, new AbstractListener() {
|
||||||
@Override
|
@Override
|
||||||
|
@@ -46,25 +46,6 @@ public class DbIsvManager extends CacheIsvManager {
|
|||||||
@PostConstruct
|
@PostConstruct
|
||||||
protected void after() throws Exception {
|
protected void after() throws Exception {
|
||||||
ApiConfig.getInstance().setIsvManager(this);
|
ApiConfig.getInstance().setIsvManager(this);
|
||||||
/*ZookeeperContext.setEnvironment(environment);
|
|
||||||
String isvChannelPath = ZookeeperContext.getIsvInfoChannelPath();
|
|
||||||
ZookeeperContext.listenPath(isvChannelPath, nodeCache -> {
|
|
||||||
String nodeData = new String(nodeCache.getCurrentData().getData());
|
|
||||||
ChannelMsg channelMsg = JSON.parseObject(nodeData, ChannelMsg.class);
|
|
||||||
final IsvDefinition isvDefinition = JSON.parseObject(channelMsg.getData(), IsvDefinition.class);
|
|
||||||
switch (channelMsg.getOperation()) {
|
|
||||||
case "update":
|
|
||||||
log.info("更新ISV信息,isvDefinition:{}", isvDefinition);
|
|
||||||
update(isvDefinition);
|
|
||||||
break;
|
|
||||||
case "remove":
|
|
||||||
log.info("删除ISV,isvDefinition:{}", isvDefinition);
|
|
||||||
remove(isvDefinition.getAppKey());
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
|
|
||||||
}
|
|
||||||
});*/
|
|
||||||
|
|
||||||
ConfigService configService = nacosConfigProperties.configServiceInstance();
|
ConfigService configService = nacosConfigProperties.configServiceInstance();
|
||||||
configService.addListener(NacosConfigs.DATA_ID_ISV, NacosConfigs.GROUP_CHANNEL, new AbstractListener() {
|
configService.addListener(NacosConfigs.DATA_ID_ISV, NacosConfigs.GROUP_CHANNEL, new AbstractListener() {
|
||||||
|
@@ -127,42 +127,6 @@ public class DbIsvRoutePermissionManager extends DefaultIsvRoutePermissionManage
|
|||||||
|
|
||||||
@PostConstruct
|
@PostConstruct
|
||||||
protected void after() throws Exception {
|
protected void after() throws Exception {
|
||||||
/*ZookeeperContext.setEnvironment(environment);
|
|
||||||
String isvChannelPath = ZookeeperContext.getIsvRoutePermissionChannelPath();
|
|
||||||
ZookeeperContext.listenPath(isvChannelPath, nodeCache -> {
|
|
||||||
String nodeData = new String(nodeCache.getCurrentData().getData());
|
|
||||||
ChannelMsg channelMsg = JSON.parseObject(nodeData, ChannelMsg.class);
|
|
||||||
final IsvRoutePermission isvRoutePermission = JSON.parseObject(channelMsg.getData(), IsvRoutePermission.class);
|
|
||||||
switch (channelMsg.getOperation()) {
|
|
||||||
case "reload":
|
|
||||||
log.info("重新加载路由权限信息,isvRoutePermission:{}", isvRoutePermission);
|
|
||||||
String listenPath = isvRoutePermission.getListenPath();
|
|
||||||
String code = "";
|
|
||||||
try {
|
|
||||||
load();
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("重新加载路由权限失败, channelMsg:{}", channelMsg, e);
|
|
||||||
code = e.getMessage();
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
ZookeeperContext.updatePath(listenPath, code);
|
|
||||||
} catch (Exception e1) {
|
|
||||||
log.error("重新加载路由权限信息, zookeeper操作失败, path: {}", listenPath, e1);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "update":
|
|
||||||
log.info("更新ISV路由权限信息,isvRoutePermission:{}", isvRoutePermission);
|
|
||||||
update(isvRoutePermission);
|
|
||||||
break;
|
|
||||||
case "remove":
|
|
||||||
log.info("删除ISV路由权限信息,isvRoutePermission:{}", isvRoutePermission);
|
|
||||||
remove(isvRoutePermission.getAppKey());
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
|
|
||||||
}
|
|
||||||
});*/
|
|
||||||
|
|
||||||
ConfigService configService = nacosConfigProperties.configServiceInstance();
|
ConfigService configService = nacosConfigProperties.configServiceInstance();
|
||||||
configService.addListener(NacosConfigs.DATA_ID_ROUTE_PERMISSION, NacosConfigs.GROUP_CHANNEL, new AbstractListener() {
|
configService.addListener(NacosConfigs.DATA_ID_ROUTE_PERMISSION, NacosConfigs.GROUP_CHANNEL, new AbstractListener() {
|
||||||
@Override
|
@Override
|
||||||
|
@@ -53,25 +53,6 @@ public class DbLimitConfigManager extends DefaultLimitConfigManager {
|
|||||||
|
|
||||||
@PostConstruct
|
@PostConstruct
|
||||||
protected void after() throws Exception {
|
protected void after() throws Exception {
|
||||||
/*ZookeeperContext.setEnvironment(environment);
|
|
||||||
String path = ZookeeperContext.getLimitConfigChannelPath();
|
|
||||||
ZookeeperContext.listenPath(path, nodeCache -> {
|
|
||||||
String nodeData = new String(nodeCache.getCurrentData().getData());
|
|
||||||
ChannelMsg channelMsg = JSON.parseObject(nodeData, ChannelMsg.class);
|
|
||||||
final ConfigLimitDto configLimitDto = JSON.parseObject(channelMsg.getData(), ConfigLimitDto.class);
|
|
||||||
switch (channelMsg.getOperation()) {
|
|
||||||
case "reload":
|
|
||||||
log.info("重新加载限流配置信息,configLimitDto:{}", configLimitDto);
|
|
||||||
load();
|
|
||||||
break;
|
|
||||||
case "update":
|
|
||||||
log.info("更新限流配置信息,configLimitDto:{}", configLimitDto);
|
|
||||||
update(configLimitDto);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
}
|
|
||||||
});*/
|
|
||||||
|
|
||||||
ConfigService configService = nacosConfigProperties.configServiceInstance();
|
ConfigService configService = nacosConfigProperties.configServiceInstance();
|
||||||
configService.addListener(NacosConfigs.DATA_ID_LIMIT_CONFIG, NacosConfigs.GROUP_CHANNEL, new AbstractListener() {
|
configService.addListener(NacosConfigs.DATA_ID_LIMIT_CONFIG, NacosConfigs.GROUP_CHANNEL, new AbstractListener() {
|
||||||
@Override
|
@Override
|
||||||
|
@@ -77,25 +77,6 @@ public class DbRouteConfigManager extends DefaultRouteConfigManager {
|
|||||||
|
|
||||||
@PostConstruct
|
@PostConstruct
|
||||||
protected void after() throws Exception {
|
protected void after() throws Exception {
|
||||||
/*ZookeeperContext.setEnvironment(environment);
|
|
||||||
String path = ZookeeperContext.getRouteConfigChannelPath();
|
|
||||||
ZookeeperContext.listenPath(path, nodeCache -> {
|
|
||||||
String nodeData = new String(nodeCache.getCurrentData().getData());
|
|
||||||
ChannelMsg channelMsg = JSON.parseObject(nodeData, ChannelMsg.class);
|
|
||||||
final RouteConfig routeConfig = JSON.parseObject(channelMsg.getData(), RouteConfig.class);
|
|
||||||
switch (channelMsg.getOperation()) {
|
|
||||||
case "reload":
|
|
||||||
log.info("重新加载路由配置信息,routeConfigDto:{}", routeConfig);
|
|
||||||
load();
|
|
||||||
break;
|
|
||||||
case "update":
|
|
||||||
log.info("更新路由配置信息,routeConfigDto:{}", routeConfig);
|
|
||||||
update(routeConfig);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
}
|
|
||||||
});*/
|
|
||||||
|
|
||||||
ConfigService configService = nacosConfigProperties.configServiceInstance();
|
ConfigService configService = nacosConfigProperties.configServiceInstance();
|
||||||
configService.addListener(NacosConfigs.DATA_ID_ROUTE_CONFIG, NacosConfigs.GROUP_CHANNEL, new AbstractListener() {
|
configService.addListener(NacosConfigs.DATA_ID_ROUTE_CONFIG, NacosConfigs.GROUP_CHANNEL, new AbstractListener() {
|
||||||
@Override
|
@Override
|
||||||
|
@@ -6,12 +6,9 @@ spring.application.name=api-gateway
|
|||||||
mysql.username=root
|
mysql.username=root
|
||||||
mysql.password=root
|
mysql.password=root
|
||||||
|
|
||||||
# eureka注册中心地址
|
|
||||||
eureka.url=http://localhost:1111/eureka/
|
|
||||||
# zookeeper地址
|
|
||||||
zookeeper.url=localhost:2181
|
|
||||||
# nacos地址
|
# nacos地址
|
||||||
nacos.url=127.0.0.1:8848
|
nacos.url=127.0.0.1:8848
|
||||||
|
|
||||||
# zipkin服务监控地址,没有开启不用改
|
# zipkin服务监控地址,没有开启不用改
|
||||||
zipkin.url=http://127.0.0.1:9411/
|
zipkin.url=http://127.0.0.1:9411/
|
||||||
|
|
||||||
@@ -40,9 +37,6 @@ ribbon.OkToRetryOnAllOperations=false
|
|||||||
# nacos cloud配置
|
# nacos cloud配置
|
||||||
spring.cloud.nacos.discovery.server-addr=${nacos.url}
|
spring.cloud.nacos.discovery.server-addr=${nacos.url}
|
||||||
|
|
||||||
# zookeeper配置
|
|
||||||
spring.cloud.zookeeper.connect-string=${zookeeper.url}
|
|
||||||
|
|
||||||
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
|
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
|
||||||
spring.datasource.url=jdbc:mysql://localhost:3306/sop?useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull
|
spring.datasource.url=jdbc:mysql://localhost:3306/sop?useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull
|
||||||
spring.datasource.username=${mysql.username}
|
spring.datasource.username=${mysql.username}
|
||||||
|
@@ -1,16 +0,0 @@
|
|||||||
package com.gitee.sop.websiteserver.bean;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author tanghc
|
|
||||||
*/
|
|
||||||
public class WebsiteConstants {
|
|
||||||
/**
|
|
||||||
* zookeeper存放接口路由信息的根目录
|
|
||||||
*/
|
|
||||||
public static final String SOP_SERVICE_ROUTE_PATH = "/com.gitee.sop.route";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 服务临时节点
|
|
||||||
*/
|
|
||||||
public static final String SOP_SERVICE_TEMP_PATH = "/com.gitee.sop.service.tmp";
|
|
||||||
}
|
|
@@ -2,11 +2,8 @@ server.port=8083
|
|||||||
spring.application.name=website-server
|
spring.application.name=website-server
|
||||||
|
|
||||||
# ------- 需要改的配置 -------
|
# ------- 需要改的配置 -------
|
||||||
# zookeeper地址
|
|
||||||
zookeeper.url=localhost:2181
|
|
||||||
# nacos地址
|
# nacos地址
|
||||||
nacos.url=127.0.0.1:8848
|
nacos.url=127.0.0.1:8848
|
||||||
|
|
||||||
# ------- 需要改的配置end -------
|
# ------- 需要改的配置end -------
|
||||||
|
|
||||||
# nacos cloud配置
|
# nacos cloud配置
|
||||||
|
Reference in New Issue
Block a user