parent
4c744ab351
commit
eed300274c
@ -0,0 +1,41 @@
|
||||
# SpringCloud - Gateway
|
||||
|
||||
|
||||
## 1. 基础介绍
|
||||
|
||||
- SpringCloud Gateway 的核心概念
|
||||
- SpringCloud Gateway 是 Spring 官方最新推出的一款基于 SpringFramework 5, Project Reactor 和SpringBoot 2之上开发的网关
|
||||
- 它与第一代网关 Zuu 不同的是: gateway 是异步非阻塞的(netty + webflux 实现), zuul是同步阻塞请求的
|
||||
- Gateway 三大组成部分
|
||||
- Route 路由(ID + 目标URL) - Predicate 断言 - Filter 过滤器
|
||||
|
||||
|
||||
- SpringCloud Gateway 的工作模型
|
||||
- SpringCloud Gateway 工作模型图示及解读
|
||||
- 请求发送到网关,经由分发器将请求匹配到相应的 HandlerMapping
|
||||
- 请求和处理器之间有一个映射,路由到网关处理程序,即 Web Handler
|
||||
- 执行特定的请求过滤器链 (Filters Proxy Filter)
|
||||
- 最终到达代理的微服务 (Proxied Service)
|
||||
---
|
||||
## 2. 谓词 Predicate 的原理与应用
|
||||
|
||||
- 参考: [PredicateTest.java]
|
||||
|
||||
## 3. 集成 Nacos 实现动态路由配置
|
||||
|
||||
- 静态路由配置
|
||||
- 静态路由配置写在配置文件中(yml或者 properties 文件中),端点是:spring.cloud.gateway
|
||||
- 缺点非常明显,每次改动都需要网关模块重新部署
|
||||
---
|
||||
## 4. 注册网关事件监听器
|
||||
|
||||
- 参考: [DynamicRouteServiceImpl.java] | [DynamicRouteServiceImplByNacos.java]
|
||||
|
||||
- 验证网关监听器的可用性 修改看是否可以生效, 已经测试成功
|
||||
|
||||
---
|
||||
## 5. 解读 SpringCloud Gateway Filter
|
||||
|
||||
|
||||
|
||||
|
@ -1,3 +0,0 @@
|
||||
# SpringCloud - Gateway
|
||||
|
||||
- 对 SpringCloud - Gateway 进行研究
|
@ -0,0 +1,17 @@
|
||||
package org.example;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
|
||||
|
||||
/**
|
||||
* <h1>网关启动入口</h1>
|
||||
* */
|
||||
@EnableDiscoveryClient
|
||||
@SpringBootApplication
|
||||
public class GatewayApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(GatewayApplication.class, args);
|
||||
}
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
package org.example;
|
||||
|
||||
public class Main {
|
||||
public static void main(String[] args) {
|
||||
System.out.println("Hello world!");
|
||||
}
|
||||
}
|
@ -0,0 +1,122 @@
|
||||
package org.example.conf;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.cloud.gateway.event.RefreshRoutesEvent;
|
||||
import org.springframework.cloud.gateway.route.RouteDefinition;
|
||||
import org.springframework.cloud.gateway.route.RouteDefinitionLocator;
|
||||
import org.springframework.cloud.gateway.route.RouteDefinitionWriter;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.context.ApplicationEventPublisherAware;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 事件推送 Aware: 动态更新路由网关 Service
|
||||
*
|
||||
* 实现 ApplicationEventPublisherAware 事件推送接口
|
||||
* */
|
||||
@Slf4j
|
||||
@Service
|
||||
@SuppressWarnings("all")
|
||||
public class DynamicRouteServiceImpl implements ApplicationEventPublisherAware {
|
||||
|
||||
/** 写路由定义 */
|
||||
private final RouteDefinitionWriter routeDefinitionWriter;
|
||||
/** 获取路由定义 */
|
||||
private final RouteDefinitionLocator routeDefinitionLocator;
|
||||
|
||||
/** 事件发布 */
|
||||
private ApplicationEventPublisher publisher;
|
||||
|
||||
public DynamicRouteServiceImpl(RouteDefinitionWriter routeDefinitionWriter,
|
||||
RouteDefinitionLocator routeDefinitionLocator) {
|
||||
this.routeDefinitionWriter = routeDefinitionWriter;
|
||||
this.routeDefinitionLocator = routeDefinitionLocator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
|
||||
// 完成事件推送句柄的初始化
|
||||
this.publisher = applicationEventPublisher;
|
||||
}
|
||||
|
||||
/**
|
||||
* <h2>增加路由定义</h2>
|
||||
* */
|
||||
public String addRouteDefinition(RouteDefinition definition) {
|
||||
|
||||
log.info("gateway add route: [{}]", definition);
|
||||
|
||||
// 保存路由配置并发布
|
||||
routeDefinitionWriter.save(Mono.just(definition)).subscribe();
|
||||
// 发布事件通知给 Gateway, 同步新增的路由定义
|
||||
this.publisher.publishEvent(new RefreshRoutesEvent(this));
|
||||
|
||||
return "success";
|
||||
}
|
||||
|
||||
/**
|
||||
* <h2>更新路由</h2>
|
||||
* */
|
||||
public String updateList(List<RouteDefinition> definitions) {
|
||||
|
||||
log.info("gateway update route: [{}]", definitions);
|
||||
|
||||
// 先拿到当前 Gateway 中存储的路由定义
|
||||
List<RouteDefinition> routeDefinitionsExits =
|
||||
routeDefinitionLocator.getRouteDefinitions().buffer().blockFirst();
|
||||
if (!CollectionUtils.isEmpty(routeDefinitionsExits)) {
|
||||
// 清除掉之前所有的 "旧的" 路由定义
|
||||
routeDefinitionsExits.forEach(rd -> {
|
||||
log.info("delete route definition: [{}]", rd);
|
||||
deleteById(rd.getId());
|
||||
});
|
||||
}
|
||||
|
||||
// 把更新的路由定义同步到 gateway 中
|
||||
definitions.forEach(definition -> updateByRouteDefinition(definition));
|
||||
return "success";
|
||||
}
|
||||
|
||||
/**
|
||||
* <h2>根据路由 id 删除路由配置</h2>
|
||||
* */
|
||||
private String deleteById(String id) {
|
||||
|
||||
try {
|
||||
log.info("gateway delete route id: [{}]", id);
|
||||
this.routeDefinitionWriter.delete(Mono.just(id)).subscribe();
|
||||
// 发布事件通知给 gateway 更新路由定义
|
||||
this.publisher.publishEvent(new RefreshRoutesEvent(this));
|
||||
return "delete success";
|
||||
} catch (Exception ex) {
|
||||
log.error("gateway delete route fail: [{}]", ex.getMessage(), ex);
|
||||
return "delete fail";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <h2>更新路由</h2>
|
||||
* 更新的实现策略比较简单: 删除 + 新增 = 更新
|
||||
* */
|
||||
private String updateByRouteDefinition(RouteDefinition definition) {
|
||||
|
||||
try {
|
||||
log.info("gateway update route: [{}]", definition);
|
||||
this.routeDefinitionWriter.delete(Mono.just(definition.getId()));
|
||||
} catch (Exception ex) {
|
||||
return "update fail, not find route routeId: " + definition.getId();
|
||||
}
|
||||
|
||||
try {
|
||||
this.routeDefinitionWriter.save(Mono.just(definition)).subscribe();
|
||||
this.publisher.publishEvent(new RefreshRoutesEvent(this));
|
||||
return "success";
|
||||
} catch (Exception ex) {
|
||||
return "update route fail";
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,127 @@
|
||||
package org.example.conf;
|
||||
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.nacos.api.NacosFactory;
|
||||
import com.alibaba.nacos.api.config.ConfigService;
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import com.alibaba.nacos.api.config.listener.Listener;
|
||||
import com.alibaba.nacos.common.utils.CollectionUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.cloud.gateway.route.RouteDefinition;
|
||||
import org.springframework.context.annotation.DependsOn;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* <h1>通过 nacos 下发动态路由配置, 监听 Nacos 中路由配置变更</h1>
|
||||
* */
|
||||
@Slf4j
|
||||
@Component
|
||||
@DependsOn({"gatewayConfig"}) // 依赖于 GatewayConfig 这个 Bean , 注意要首字母小写
|
||||
public class DynamicRouteServiceImplByNacos {
|
||||
/** Nacos 配置服务 */
|
||||
private ConfigService configService;
|
||||
private final DynamicRouteServiceImpl dynamicRouteService;
|
||||
|
||||
public DynamicRouteServiceImplByNacos(DynamicRouteServiceImpl dynamicRouteService) {
|
||||
this.dynamicRouteService = dynamicRouteService;
|
||||
}
|
||||
|
||||
/**
|
||||
* <h2>Bean 在容器中构造完成之后会执行 init 方法</h2>
|
||||
* */
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
|
||||
log.info("gateway route init....");
|
||||
|
||||
try {
|
||||
// 初始化 Nacos 配置客户端
|
||||
configService = initConfigService();
|
||||
if (null == configService) {
|
||||
log.error("init config service fail");
|
||||
return;
|
||||
}
|
||||
|
||||
// 通过 Nacos Config 并指定路由配置路径去获取路由配置
|
||||
String configInfo = configService.getConfig(
|
||||
GatewayConfig.NACOS_ROUTE_DATA_ID,
|
||||
GatewayConfig.NACOS_ROUTE_GROUP,
|
||||
GatewayConfig.DEFAULT_TIMEOUT
|
||||
);
|
||||
|
||||
log.info("get current gateway config: [{}]", configInfo);
|
||||
List<RouteDefinition> definitionList = JSON.parseArray(configInfo, RouteDefinition.class);
|
||||
|
||||
if (CollectionUtils.isNotEmpty(definitionList)) {
|
||||
for (RouteDefinition definition : definitionList) {
|
||||
log.info("init gateway config: [{}]", definition.toString());
|
||||
dynamicRouteService.addRouteDefinition(definition);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception ex) {
|
||||
log.error("gateway route init has some error: [{}]", ex.getMessage(), ex);
|
||||
}
|
||||
|
||||
// 设置监听器
|
||||
dynamicRouteByNacosListener(GatewayConfig.NACOS_ROUTE_DATA_ID, GatewayConfig.NACOS_ROUTE_GROUP);
|
||||
}
|
||||
|
||||
/**
|
||||
* <h2>初始化 Nacos Config</h2>
|
||||
* */
|
||||
private ConfigService initConfigService() {
|
||||
|
||||
try {
|
||||
Properties properties = new Properties();
|
||||
properties.setProperty("serverAddr", GatewayConfig.NACOS_SERVER_ADDR);
|
||||
properties.setProperty("namespace", GatewayConfig.NACOS_NAMESPACE);
|
||||
return configService = NacosFactory.createConfigService(properties);
|
||||
} catch (Exception ex) {
|
||||
log.error("init gateway nacos config error: [{}]", ex.getMessage(), ex);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <h2>监听 Nacos 下发的动态路由配置</h2>
|
||||
* */
|
||||
private void dynamicRouteByNacosListener(String dataId, String group) {
|
||||
|
||||
try {
|
||||
// 给 Nacos Config 客户端增加一个监听器
|
||||
configService.addListener(dataId, group, new Listener() {
|
||||
|
||||
/**
|
||||
* <h2>自己提供线程池执行操作</h2>
|
||||
* */
|
||||
@Override
|
||||
public Executor getExecutor() {
|
||||
// 通常不需要自己提供用默认提供的即可
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* <h2>监听器收到配置更新</h2>
|
||||
* @param configInfo Nacos 中最新的配置定义
|
||||
* */
|
||||
@Override
|
||||
public void receiveConfigInfo(String configInfo) {
|
||||
|
||||
log.info("start to update config: [{}]", configInfo);
|
||||
List<RouteDefinition> definitionList = JSON.parseArray(configInfo, RouteDefinition.class);
|
||||
log.info("update route: [{}]", definitionList.toString());
|
||||
dynamicRouteService.updateList(definitionList);
|
||||
}
|
||||
});
|
||||
} catch (NacosException ex) {
|
||||
log.error("dynamic update gateway config error: [{}]", ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
package org.example.conf;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* <h1>配置类, 读取 Nacos 相关的配置项, 用于配置监听器</h1>
|
||||
* */
|
||||
@Configuration
|
||||
public class GatewayConfig {
|
||||
|
||||
/** 读取配置的超时时间 */
|
||||
public static final long DEFAULT_TIMEOUT = 30000;
|
||||
|
||||
/** Nacos 服务器地址 */
|
||||
public static String NACOS_SERVER_ADDR;
|
||||
|
||||
/** 命名空间 */
|
||||
public static String NACOS_NAMESPACE;
|
||||
|
||||
/** data-id */
|
||||
public static String NACOS_ROUTE_DATA_ID;
|
||||
|
||||
/** 分组 id */
|
||||
public static String NACOS_ROUTE_GROUP;
|
||||
|
||||
@Value("${spring.cloud.nacos.discovery.server-addr}")
|
||||
public void setNacosServerAddr(String nacosServerAddr) {
|
||||
NACOS_SERVER_ADDR = nacosServerAddr;
|
||||
}
|
||||
|
||||
@Value("${spring.cloud.nacos.discovery.namespace}")
|
||||
public void setNacosNamespace(String nacosNamespace) {
|
||||
NACOS_NAMESPACE = nacosNamespace;
|
||||
}
|
||||
|
||||
@Value("${nacos.gateway.route.config.data-id}")
|
||||
public void setNacosRouteDataId(String nacosRouteDataId) {
|
||||
NACOS_ROUTE_DATA_ID = nacosRouteDataId;
|
||||
}
|
||||
|
||||
@Value("${nacos.gateway.route.config.group}")
|
||||
public void setNacosRouteGroup(String nacosRouteGroup) {
|
||||
NACOS_ROUTE_GROUP = nacosRouteGroup;
|
||||
}
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
server:
|
||||
port: 9001
|
||||
servlet:
|
||||
context-path: /dev-protocol-springcloud-gateway
|
||||
|
||||
spring:
|
||||
application:
|
||||
name: dev-protocol-springcloud-gateway
|
||||
cloud:
|
||||
nacos:
|
||||
discovery:
|
||||
enabled: true # 如果不想使用 Nacos 进行服务注册和发现, 设置为 false 即可
|
||||
server-addr: 127.0.0.1:8848 # Nacos 服务器地址
|
||||
namespace: 1ccc74ae-9398-4dbe-b9d7-4f9addf9f40c
|
||||
metadata:
|
||||
management:
|
||||
context-path: ${server.servlet.context-path}/actuator
|
||||
# 静态路由
|
||||
# gateway:
|
||||
# routes:
|
||||
# - id: path_route # 路由的ID
|
||||
# uri: 127.0.0.1:8080/user/{id} # 匹配后路由地址
|
||||
# predicates: # 断言, 路径相匹配的进行路由
|
||||
# - Path=/user/{id}
|
||||
# kafka:
|
||||
# bootstrap-servers: 127.0.0.1:9092
|
||||
# producer:
|
||||
# retries: 3
|
||||
# consumer:
|
||||
# auto-offset-reset: latest
|
||||
# zipkin:
|
||||
# sender:
|
||||
# type: kafka # 默认是 web
|
||||
# base-url: http://localhost:9411/
|
||||
main:
|
||||
allow-bean-definition-overriding: true # 因为将来会引入很多依赖, 难免有重名的 bean
|
||||
|
||||
# 这个地方独立配置, 是网关的数据, 代码 GatewayConfig.java 中读取被监听
|
||||
nacos:
|
||||
gateway:
|
||||
route:
|
||||
config:
|
||||
data-id: dev-protocol-springcloud-gateway-router
|
||||
group: dev-protocol
|
||||
|
||||
# 暴露端点
|
||||
management:
|
||||
endpoints:
|
||||
web:
|
||||
exposure:
|
||||
include: '*'
|
||||
endpoint:
|
||||
health:
|
||||
show-details: always
|
@ -0,0 +1,17 @@
|
||||
### 登录
|
||||
POST 127.0.0.1:9001/imooc/e-commerce/login
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"username": "Qinyi@imooc.com",
|
||||
"password": "25d55ad283aa400af464c76d713c07ad"
|
||||
}
|
||||
|
||||
###
|
||||
POST 127.0.0.1:9001/imooc/e-commerce/register
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"username": "ImoocQinyi@imooc.com",
|
||||
"password": "25d55ad283aa400af464c76d713c07ad"
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
### 查询服务
|
||||
GET http://127.0.0.1:9001/imooc/ecommerce-nacos-client/nacos-client/service-instance?serviceId=e-commerce-gateway
|
||||
Accept: application/json
|
||||
e-commerce-user: eyJhbGciOiJSUzI1NiJ9.eyJlLWNvbW1lcmNlLXVzZXIiOiJ7XCJpZFwiOjE3LFwidXNlcm5hbWVcIjpcIkltb29jUWlueWlAaW1vb2MuY29tXCJ9IiwianRpIjoiMGIxNzQyYWItMWU3OC00OTZjLWIyNTAtMjNkZGQ1ZGEyZTU1IiwiZXhwIjoxNjI0MjA0ODAwfQ.QKGHzohSHdYDHzUVHpe9gNPUgzfkPwrSbB-WiMWYjLlt2tr9BufzZM8bSt-whb_bd0hKoC6rkYYO0WUVR67uSML-2yaTL1xMIn8GH9Flyig3rpO4vefL3Hp2TXIpwHHa7WlKsLzcUpNk9lxWs2B5k0ICdYCH_jD5Tx6N7CzfSUG9u4fOnVeM9UFE2nX_DURupUh_DKCc2oOoMeyCSR7Ma8-Ab4WQU3r-U0YivR8G1A0kmKOIoTeRhM3LcPuxUPh3rCbrjzMg--fexRGw0O38Qsby6pz-ku2IlTyFXY6_jNOG1BZR34-jBOnaIciP1TExw9bFumeuC2GcowTHJVH1Nw
|
||||
token: imooc
|
@ -0,0 +1,18 @@
|
||||
package org.example;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
/**
|
||||
* <h1>验证工程搭建的正确性测试用例</h1>
|
||||
* */
|
||||
@SpringBootTest
|
||||
@RunWith(SpringRunner.class)
|
||||
public class GatewayApplicationTest {
|
||||
|
||||
@Test
|
||||
public void contextLoad() {
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,83 @@
|
||||
package org.example.service;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
* <h1>Java8 Predicate 使用方法与思想</h1>
|
||||
* */
|
||||
@Slf4j
|
||||
@SpringBootTest
|
||||
@RunWith(SpringRunner.class)
|
||||
public class PredicateTest {
|
||||
|
||||
public static List<String> MICRO_SERVICE = Arrays.asList(
|
||||
"nacos", "authority", "gateway", "ribbon", "feign", "hystrix", "e-commerce"
|
||||
);
|
||||
|
||||
/**
|
||||
* <h2>test 方法主要用于参数符不符合规则, 返回值是 boolean</h2>
|
||||
* */
|
||||
@Test
|
||||
public void testPredicateTest() {
|
||||
|
||||
Predicate<String> letterLengthLimit = s -> s.length() > 5;
|
||||
MICRO_SERVICE.stream().filter(letterLengthLimit).forEach(System.out::println);
|
||||
}
|
||||
|
||||
/**
|
||||
* <h2>and 方法等同于我们的逻辑与 &&, 存在短路特性, 需要所有的条件都满足</h2>
|
||||
* */
|
||||
@Test
|
||||
public void testPredicateAnd() {
|
||||
|
||||
Predicate<String> letterLengthLimit = s -> s.length() > 5;
|
||||
Predicate<String> letterStartWith = s -> s.startsWith("gate");
|
||||
|
||||
MICRO_SERVICE.stream().filter(
|
||||
letterLengthLimit.and(letterStartWith)
|
||||
).forEach(System.out::println);
|
||||
}
|
||||
|
||||
/**
|
||||
* <h2>or 等同于我们的逻辑或 ||, 多个条件主要一个满足即可</h2>
|
||||
* */
|
||||
@Test
|
||||
public void testPredicateOr() {
|
||||
|
||||
Predicate<String> letterLengthLimit = s -> s.length() > 5;
|
||||
Predicate<String> letterStartWith = s -> s.startsWith("gate");
|
||||
|
||||
MICRO_SERVICE.stream().filter(
|
||||
letterLengthLimit.or(letterStartWith)
|
||||
).forEach(System.out::println);
|
||||
}
|
||||
|
||||
/**
|
||||
* <h2>negate 等同于我们的逻辑非 !</h2>
|
||||
* */
|
||||
@Test
|
||||
public void testPredicateNegate() {
|
||||
|
||||
Predicate<String> letterStartWith = s -> s.startsWith("gate");
|
||||
MICRO_SERVICE.stream().filter(letterStartWith.negate()).forEach(System.out::println);
|
||||
}
|
||||
|
||||
/**
|
||||
* <h2>isEqual 类似于 equals(), 区别在于: 先判断对象是否为 NULL,
|
||||
* 不为 NULL 再使用 equals 进行比较</h2>
|
||||
* */
|
||||
@Test
|
||||
public void testPredicateIsEqual() {
|
||||
|
||||
Predicate<String> equalGateway = s -> Predicate.isEqual("gateway").test(s);
|
||||
MICRO_SERVICE.stream().filter(equalGateway).forEach(System.out::println);
|
||||
}
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
package org.example.controller;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.example.service.NacosClientService;
|
||||
import org.springframework.cloud.client.ServiceInstance;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <h1>nacos client controller</h1>
|
||||
* */
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/nacos-client")
|
||||
public class NacosClientController {
|
||||
|
||||
private final NacosClientService nacosClientService;
|
||||
// private final ProjectConfig projectConfig;
|
||||
|
||||
|
||||
public NacosClientController(NacosClientService nacosClientService
|
||||
// ProjectConfig projectConfig
|
||||
) {
|
||||
this.nacosClientService = nacosClientService;
|
||||
// this.projectConfig = projectConfig;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* <h2>根据 service id 获取服务所有的实例信息</h2>
|
||||
* */
|
||||
@GetMapping("/service-instance")
|
||||
public List<ServiceInstance> logNacosClientInfo(
|
||||
@RequestParam(defaultValue = "dev-protocol-spring-cloud-nacos") String serviceId) {
|
||||
|
||||
log.info("coming in log nacos client info: [{}]", serviceId);
|
||||
return nacosClientService.getNacosClientInfo(serviceId);
|
||||
}
|
||||
|
||||
/* *//**
|
||||
* <h2>动态获取 Nacos 中的配置信息</h2>
|
||||
* *//*
|
||||
@GetMapping("/project-config")
|
||||
public ProjectConfig getProjectConfig() {
|
||||
return projectConfig;
|
||||
}*/
|
||||
}
|
@ -1,13 +1,13 @@
|
||||
### 查询服务实例信息
|
||||
GET http://127.0.0.1:8000/ecommerce-nacos-client/nacos-client/service-instance
|
||||
GET http://127.0.0.1:8000/dev-protocol-spring-cloud-nacos/nacos-client/service-instance
|
||||
Accept: application/json
|
||||
|
||||
### 动态从 Nacos Server 中获取配置信息
|
||||
GET http://127.0.0.1:8000/ecommerce-nacos-client/nacos-client/project-config
|
||||
GET http://127.0.0.1:8000/dev-protocol-spring-cloud-nacos/nacos-client/project-config
|
||||
Accept: application/json
|
||||
|
||||
### 查看 Sleuth 跟踪信息
|
||||
GET http://127.0.0.1:9001/imooc/ecommerce-nacos-client/sleuth/trace-info
|
||||
GET http://127.0.0.1:9001/imooc/dev-protocol-spring-cloud-nacos/sleuth/trace-info
|
||||
Accept: application/json
|
||||
e-commerce-user: eyJhbGciOiJSUzI1NiJ9.eyJlLWNvbW1lcmNlLXVzZXIiOiJ7XCJpZFwiOjE3LFwidXNlcm5hbWVcIjpcIkltb29jUWlueWlAaW1vb2MuY29tXCJ9IiwianRpIjoiMGIxNzQyYWItMWU3OC00OTZjLWIyNTAtMjNkZGQ1ZGEyZTU1IiwiZXhwIjoxNjI0MjA0ODAwfQ.QKGHzohSHdYDHzUVHpe9gNPUgzfkPwrSbB-WiMWYjLlt2tr9BufzZM8bSt-whb_bd0hKoC6rkYYO0WUVR67uSML-2yaTL1xMIn8GH9Flyig3rpO4vefL3Hp2TXIpwHHa7WlKsLzcUpNk9lxWs2B5k0ICdYCH_jD5Tx6N7CzfSUG9u4fOnVeM9UFE2nX_DURupUh_DKCc2oOoMeyCSR7Ma8-Ab4WQU3r-U0YivR8G1A0kmKOIoTeRhM3LcPuxUPh3rCbrjzMg--fexRGw0O38Qsby6pz-ku2IlTyFXY6_jNOG1BZR34-jBOnaIciP1TExw9bFumeuC2GcowTHJVH1Nw
|
||||
token: imooc
|
||||
|
Loading…
Reference in New Issue