From 7aa17d376040705bc403f156e343668362fa9990 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=8F=E9=A9=AC=E5=93=A5?= Date: Mon, 14 Jan 2019 10:44:11 +0800 Subject: [PATCH] Temporary commit --- .../DubboRestAutoConfiguration.java | 32 ++-- .../DubboRestDiscoveryAutoConfiguration.java | 169 ++++++++++++++++-- ...MetadataRegistrationAutoConfiguration.java | 38 +++- .../main/resources/META-INF/spring.factories | 4 +- .../bootstrap/DubboSpringCloudBootstrap.java | 31 +++- .../dubbo/service/DefaultEchoService.java | 11 +- .../src/test/resources/application.yaml | 2 +- .../src/test/resources/bootstrap.yaml | 1 - .../nacos-discovery-consumer-example/pom.xml | 24 ++- .../demos/SpringCloudRestClientBootstrap.java | 42 +++++ .../src/main/resources/application.properties | 7 +- 11 files changed, 309 insertions(+), 52 deletions(-) create mode 100644 spring-cloud-alibaba-examples/nacos-example/nacos-discovery-example/nacos-discovery-consumer-example/src/main/java/org/springframework/cloud/alibaba/cloud/examples/demos/SpringCloudRestClientBootstrap.java diff --git a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/autoconfigure/DubboRestAutoConfiguration.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/autoconfigure/DubboRestAutoConfiguration.java index 58528da7..7af8faeb 100644 --- a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/autoconfigure/DubboRestAutoConfiguration.java +++ b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/autoconfigure/DubboRestAutoConfiguration.java @@ -37,14 +37,14 @@ import javax.ws.rs.Path; @Configuration public class DubboRestAutoConfiguration { - /** - * A Feign Contract bean for JAX-RS if available - */ - @ConditionalOnClass(Path.class) - @Bean - public Contract jaxrs2Contract() { - return new JAXRS2Contract(); - } +// /** +// * A Feign Contract bean for JAX-RS if available +// */ +// @ConditionalOnClass(Path.class) +// @Bean +// public Contract jaxrs2Contract() { +// return new JAXRS2Contract(); +// } @Bean @ConditionalOnMissingBean @@ -52,14 +52,14 @@ public class DubboRestAutoConfiguration { return new ObjectMapper(); } - /** - * A Feign Contract bean for Spring MVC if available - */ - @ConditionalOnClass(RequestMapping.class) - @Bean - public Contract springMvcContract() { - return new SpringMvcContract(); - } +// /** +// * A Feign Contract bean for Spring MVC if available +// */ +// @ConditionalOnClass(RequestMapping.class) +// @Bean +// public Contract springMvcContract() { +// return new SpringMvcContract(); +// } @Bean public RestMetadataResolver metadataJsonResolver(ObjectMapper objectMapper) { diff --git a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/autoconfigure/DubboRestDiscoveryAutoConfiguration.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/autoconfigure/DubboRestDiscoveryAutoConfiguration.java index ddb2fd2b..93fdc338 100644 --- a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/autoconfigure/DubboRestDiscoveryAutoConfiguration.java +++ b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/autoconfigure/DubboRestDiscoveryAutoConfiguration.java @@ -16,10 +16,23 @@ */ package org.springframework.cloud.alibaba.dubbo.autoconfigure; +import com.alibaba.dubbo.config.ApplicationConfig; +import com.alibaba.dubbo.config.RegistryConfig; +import com.alibaba.dubbo.config.spring.ReferenceBean; +import feign.Client; +import feign.Request; +import feign.Response; +import org.codehaus.jackson.map.ObjectMapper; +import org.springframework.beans.BeansException; import org.springframework.beans.factory.ListableBeanFactory; import org.springframework.beans.factory.SmartInitializingSingleton; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.boot.autoconfigure.AutoConfigureAfter; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.cloud.alibaba.dubbo.rest.feign.RestMetadataResolver; +import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.client.discovery.DiscoveryClient; import org.springframework.cloud.context.named.NamedContextFactory; import org.springframework.cloud.openfeign.FeignClient; @@ -27,8 +40,18 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.event.ContextRefreshedEvent; import org.springframework.context.event.EventListener; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.util.StringUtils; +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; /** * The Auto-Configuration class for Dubbo REST Discovery @@ -41,28 +64,148 @@ import java.util.Map; DubboRestMetadataRegistrationAutoConfiguration.class}) public class DubboRestDiscoveryAutoConfiguration { - @Autowired private DiscoveryClient discoveryClient; - // 1. Get all service names from Spring beans that was annotated by @FeignClient - // 2. Get all service instances by echo specified service name - // 3. Get Rest metadata from service instance - // 4. Resolve REST metadata from the @FeignClient instance + @Autowired + private RestMetadataResolver restMetadataResolver; + + @Autowired(required = false) + private ObjectMapper objectMapper = new ObjectMapper(); + + /** + * Feign Request -> Dubbo ReferenceBean + */ + private Map referenceBeanCache = new HashMap<>(); + + @Autowired + private ApplicationConfig applicationConfig; + + @Value("${spring.cloud.nacos.discovery.server-addr}") + private String nacosServerAddress; + + + private volatile boolean initialized = false; + + @Autowired + private ListableBeanFactory beanFactory; + + @Scheduled(initialDelay = 10 * 1000, fixedRate = 5000) + public void init() { + + if (initialized) { + return; + } + + Map specifications = + beanFactory.getBeansOfType(NamedContextFactory.Specification.class); + ServiceAnnotationBeanPostProcessor + // 1. Get all service names from Spring beans that was annotated by @FeignClient + List serviceNames = new LinkedList<>(); + + specifications.forEach((beanName, specification) -> { + String serviceName = beanName.substring(0, beanName.indexOf(".")); + serviceNames.add(serviceName); + + // 2. Get all service instances by echo specified service name + List serviceInstances = discoveryClient.getInstances(serviceName); + if (!serviceInstances.isEmpty()) { + ServiceInstance serviceInstance = serviceInstances.get(0); + // 3. Get Rest metadata from service instance + Map metadata = serviceInstance.getMetadata(); + // 4. Resolve REST metadata from the @FeignClient instance + String restMetadataJson = metadata.get("restMetadata"); + /** + * { + * "providers:org.springframework.cloud.alibaba.dubbo.service.EchoService:1.0.0": [ + * "{\"method\":\"POST\",\"url\":\"/plus?a={a}&b={b}\",\"headers\":{}}", + * "{\"method\":\"GET\",\"url\":\"/echo?message={message}\",\"headers\":{}}" + * ] + * } + */ + try { + Map> restMetadata = objectMapper.readValue(restMetadataJson, Map.class); + + restMetadata.forEach((dubboServiceName, restJsons) -> { + restJsons.stream().map(restMetadataResolver::resolveRequest).forEach(request -> { + referenceBeanCache.put(request.toString(), buildReferenceBean(dubboServiceName)); + }); + }); + + } catch (IOException e) { + throw new RuntimeException(e); + } + + // + } + }); + + initialized = true; + + } + + private ReferenceBean buildReferenceBean(String dubboServiceName) { + ReferenceBean referenceBean = new ReferenceBean(); + applicationConfig.setName("service-consumer"); + referenceBean.setApplication(applicationConfig); + RegistryConfig registryConfig = new RegistryConfig(); + // requires dubbo-registry-nacos + registryConfig.setAddress("nacos://" + nacosServerAddress); + referenceBean.setRegistry(registryConfig); + String[] parts = StringUtils.delimitedListToStringArray(dubboServiceName, ":"); + referenceBean.setInterface(parts[1]); + referenceBean.setVersion(parts[2]); + referenceBean.setGroup(parts.length > 3 ? parts[3] : null); + referenceBean.get(); + return referenceBean; + } @Bean - public SmartInitializingSingleton onBeansInitialized(ListableBeanFactory beanFactory) { - return () -> { - Map feignClientBeans = beanFactory.getBeansWithAnnotation(FeignClient.class); - feignClientBeans.forEach((beanName, bean) -> { - if (bean instanceof NamedContextFactory.Specification) { - NamedContextFactory.Specification specification = (NamedContextFactory.Specification) bean; - String serviceName = specification.getName(); + public BeanPostProcessor wrapClientBeanPostProcessor() { + return new BeanPostProcessor() { + public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { + if (bean instanceof Client) { + Client client = (Client) bean; + // wrapper + return new DubboFeignClientProxy(client); } - }); + return bean; + } }; } + class DubboFeignClientProxy implements Client { + + private final Client delegate; + + DubboFeignClientProxy(Client delegate) { + this.delegate = delegate; + } + + @Override + public Response execute(Request request, Request.Options options) throws IOException { + + ReferenceBean referenceBean = referenceBeanCache.get(request.toString()); + + if (referenceBean != null) { + Object dubboClient = referenceBean.get(); + Method method = null; + Object[] params = null; + + try { + Object result = method.invoke(dubboClient, params); + // wrapper as a Response + } catch (IllegalAccessException e) { + e.printStackTrace(); + } catch (InvocationTargetException e) { + e.printStackTrace(); + } + } + + return delegate.execute(request, options); + } + } + @EventListener(ContextRefreshedEvent.class) public void onContextRefreshed(ContextRefreshedEvent event) { diff --git a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/autoconfigure/DubboRestMetadataRegistrationAutoConfiguration.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/autoconfigure/DubboRestMetadataRegistrationAutoConfiguration.java index ea9af9a3..6d48f369 100644 --- a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/autoconfigure/DubboRestMetadataRegistrationAutoConfiguration.java +++ b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/autoconfigure/DubboRestMetadataRegistrationAutoConfiguration.java @@ -23,17 +23,23 @@ import com.alibaba.dubbo.config.spring.context.event.ServiceBeanExportedEvent; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import feign.Contract; +import feign.jaxrs2.JAXRS2Contract; +import org.springframework.beans.factory.BeanClassLoaderAware; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.cloud.alibaba.dubbo.rest.feign.RestMetadataResolver; import org.springframework.cloud.client.discovery.event.InstancePreRegisteredEvent; import org.springframework.cloud.client.serviceregistry.Registration; +import org.springframework.cloud.openfeign.support.SpringMvcContract; import org.springframework.context.annotation.Configuration; import org.springframework.context.event.EventListener; +import org.springframework.util.ClassUtils; +import javax.annotation.PostConstruct; import java.util.Collection; import java.util.Collections; import java.util.LinkedHashMap; +import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; @@ -51,7 +57,7 @@ import static org.springframework.cloud.alibaba.dubbo.registry.SpringCloudRegist @Configuration @AutoConfigureAfter(value = { DubboRestAutoConfiguration.class, DubboServiceRegistrationAutoConfiguration.class}) -public class DubboRestMetadataRegistrationAutoConfiguration { +public class DubboRestMetadataRegistrationAutoConfiguration implements BeanClassLoaderAware { /** * A Map to store REST metadata temporary, its' key is the special service name for a Dubbo service, @@ -60,17 +66,38 @@ public class DubboRestMetadataRegistrationAutoConfiguration { private final Map> restMetadata = new LinkedHashMap<>(); /** - * Autowire Feign Contract Beans + * Feign Contracts */ - @Autowired(required = false) private Collection contracts = Collections.emptyList(); + private ClassLoader classLoader; + @Autowired private ObjectMapper objectMapper; @Autowired private RestMetadataResolver restMetadataResolver; + @PostConstruct + public void init() { + contracts = initFeignContracts(); + } + + private Collection initFeignContracts() { + Collection contracts = new LinkedList<>(); + + if (ClassUtils.isPresent("javax.ws.rs.Path", classLoader)) { + contracts.add(new JAXRS2Contract()); + } + + if (ClassUtils.isPresent("org.springframework.web.bind.annotation.RequestMapping", classLoader)) { + contracts.add(new SpringMvcContract()); + } + + return contracts; + } + + @EventListener(ServiceBeanExportedEvent.class) public void recordRestMetadata(ServiceBeanExportedEvent event) { ServiceBean serviceBean = event.getServiceBean(); @@ -105,4 +132,9 @@ public class DubboRestMetadataRegistrationAutoConfiguration { String restMetadataJson = objectMapper.writeValueAsString(restMetadata); serviceInstanceMetadata.put("restMetadata", restMetadataJson); } + + @Override + public void setBeanClassLoader(ClassLoader classLoader) { + this.classLoader = classLoader; + } } diff --git a/spring-cloud-alibaba-dubbo/src/main/resources/META-INF/spring.factories b/spring-cloud-alibaba-dubbo/src/main/resources/META-INF/spring.factories index 3af4c939..e3cb78bf 100644 --- a/spring-cloud-alibaba-dubbo/src/main/resources/META-INF/spring.factories +++ b/spring-cloud-alibaba-dubbo/src/main/resources/META-INF/spring.factories @@ -1,3 +1,5 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ org.springframework.cloud.alibaba.dubbo.autoconfigure.DubboRestAutoConfiguration,\ - org.springframework.cloud.alibaba.dubbo.autoconfigure.DubboServiceRegistrationAutoConfiguration + org.springframework.cloud.alibaba.dubbo.autoconfigure.DubboServiceRegistrationAutoConfiguration,\ + org.springframework.cloud.alibaba.dubbo.autoconfigure.DubboRestMetadataRegistrationAutoConfiguration,\ + org.springframework.cloud.alibaba.dubbo.autoconfigure.DubboRestDiscoveryAutoConfiguration diff --git a/spring-cloud-alibaba-dubbo/src/test/java/org/springframework/cloud/alibaba/dubbo/bootstrap/DubboSpringCloudBootstrap.java b/spring-cloud-alibaba-dubbo/src/test/java/org/springframework/cloud/alibaba/dubbo/bootstrap/DubboSpringCloudBootstrap.java index 8b32a4b9..4445e880 100644 --- a/spring-cloud-alibaba-dubbo/src/test/java/org/springframework/cloud/alibaba/dubbo/bootstrap/DubboSpringCloudBootstrap.java +++ b/spring-cloud-alibaba-dubbo/src/test/java/org/springframework/cloud/alibaba/dubbo/bootstrap/DubboSpringCloudBootstrap.java @@ -29,8 +29,16 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.cloud.alibaba.dubbo.service.EchoService; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; +import org.springframework.cloud.openfeign.EnableFeignClients; +import org.springframework.cloud.openfeign.FeignClient; import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Lazy; import org.springframework.context.event.EventListener; +import org.springframework.scheduling.annotation.EnableScheduling; +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; @@ -39,18 +47,37 @@ import java.util.List; */ @EnableDiscoveryClient @EnableAutoConfiguration +@EnableFeignClients +@EnableScheduling +@RestController public class DubboSpringCloudBootstrap { @Reference(version = "1.0.0") private EchoService echoService; - @Reference(version = "1.0.0") - private EchoService echoServiceForRest; + @Autowired + @Lazy + private FeignEchoService feignEchoService; + + @GetMapping(value = "/call/echo") + public String echo(@RequestParam("message") String message) { + return feignEchoService.echo(message); + } + + @FeignClient("spring-cloud-alibaba-dubbo") + public interface FeignEchoService { + + @GetMapping(value = "/echo") + String echo(@RequestParam("message") String message); + } @Bean public ApplicationRunner applicationRunner() { return arguments -> { + // Dubbo Service call System.out.println(echoService.echo("mercyblitz")); + // Spring Cloud Open Feign REST Call + System.out.println(feignEchoService.echo("mercyblitz")); }; } diff --git a/spring-cloud-alibaba-dubbo/src/test/java/org/springframework/cloud/alibaba/dubbo/service/DefaultEchoService.java b/spring-cloud-alibaba-dubbo/src/test/java/org/springframework/cloud/alibaba/dubbo/service/DefaultEchoService.java index abc2d641..e1ad9a9d 100644 --- a/spring-cloud-alibaba-dubbo/src/test/java/org/springframework/cloud/alibaba/dubbo/service/DefaultEchoService.java +++ b/spring-cloud-alibaba-dubbo/src/test/java/org/springframework/cloud/alibaba/dubbo/service/DefaultEchoService.java @@ -43,13 +43,14 @@ import javax.ws.rs.QueryParam; public class DefaultEchoService implements EchoService { @Override - @GetMapping(value = "/echo", - consumes = MediaType.APPLICATION_JSON_VALUE, - produces = MediaType.APPLICATION_JSON_UTF8_VALUE) + @GetMapping(value = "/echo" +// consumes = MediaType.APPLICATION_JSON_VALUE, +// produces = MediaType.APPLICATION_JSON_UTF8_VALUE + ) @Path("/echo") @GET - @Consumes("application/json") - @Produces("application/json;charset=UTF-8") +// @Consumes("application/json") +// @Produces("application/json;charset=UTF-8") public String echo(@RequestParam @QueryParam("message") String message) { return RpcContext.getContext().getUrl() + " [echo] : " + message; } diff --git a/spring-cloud-alibaba-dubbo/src/test/resources/application.yaml b/spring-cloud-alibaba-dubbo/src/test/resources/application.yaml index 113a3aa5..2dc92d59 100644 --- a/spring-cloud-alibaba-dubbo/src/test/resources/application.yaml +++ b/spring-cloud-alibaba-dubbo/src/test/resources/application.yaml @@ -10,4 +10,4 @@ dubbo: port: 9090 server: netty registry: - address: spring-cloud://dummy \ No newline at end of file + address: spring-cloud://nacos \ No newline at end of file diff --git a/spring-cloud-alibaba-dubbo/src/test/resources/bootstrap.yaml b/spring-cloud-alibaba-dubbo/src/test/resources/bootstrap.yaml index 9a5062a1..c760349d 100644 --- a/spring-cloud-alibaba-dubbo/src/test/resources/bootstrap.yaml +++ b/spring-cloud-alibaba-dubbo/src/test/resources/bootstrap.yaml @@ -5,7 +5,6 @@ spring: nacos: discovery: server-addr: 127.0.0.1:8848 - port: 12345 eureka: client: enabled: false diff --git a/spring-cloud-alibaba-examples/nacos-example/nacos-discovery-example/nacos-discovery-consumer-example/pom.xml b/spring-cloud-alibaba-examples/nacos-example/nacos-discovery-example/nacos-discovery-consumer-example/pom.xml index 6a3af32b..21713a4a 100644 --- a/spring-cloud-alibaba-examples/nacos-example/nacos-discovery-example/nacos-discovery-consumer-example/pom.xml +++ b/spring-cloud-alibaba-examples/nacos-example/nacos-discovery-example/nacos-discovery-consumer-example/pom.xml @@ -16,15 +16,31 @@ + org.springframework.boot spring-boot-starter-web + org.springframework.cloud spring-cloud-starter-alibaba-nacos-discovery + + + com.alibaba + dubbo-registry-nacos + 0.0.2 + + + + + org.springframework.cloud + spring-cloud-alibaba-dubbo + ${project.version} + + org.springframework.boot spring-boot-starter-actuator @@ -40,10 +56,10 @@ spring-cloud-starter-openfeign - - org.springframework.cloud - spring-cloud-starter-alibaba-sentinel - + + + + diff --git a/spring-cloud-alibaba-examples/nacos-example/nacos-discovery-example/nacos-discovery-consumer-example/src/main/java/org/springframework/cloud/alibaba/cloud/examples/demos/SpringCloudRestClientBootstrap.java b/spring-cloud-alibaba-examples/nacos-example/nacos-discovery-example/nacos-discovery-consumer-example/src/main/java/org/springframework/cloud/alibaba/cloud/examples/demos/SpringCloudRestClientBootstrap.java new file mode 100644 index 00000000..b5b72848 --- /dev/null +++ b/spring-cloud-alibaba-examples/nacos-example/nacos-discovery-example/nacos-discovery-consumer-example/src/main/java/org/springframework/cloud/alibaba/cloud/examples/demos/SpringCloudRestClientBootstrap.java @@ -0,0 +1,42 @@ +package org.springframework.cloud.alibaba.cloud.examples.demos; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.cloud.client.discovery.EnableDiscoveryClient; +import org.springframework.cloud.openfeign.EnableFeignClients; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.context.annotation.Lazy; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@EnableAutoConfiguration // 激活自动装配 +@EnableDiscoveryClient // 激活服务注册和发现 +@EnableFeignClients // 激活 @FeignClients注册 +public class SpringCloudRestClientBootstrap { + + @FeignClient("spring-cloud-alibaba-dubbo") + public interface FeignEchoService { + + @GetMapping(value = "/echo") + String echo(@RequestParam("message") String message); + } + + + @RestController + public static class EchoServiceController { + + @Autowired + private FeignEchoService feignEchoService; + + @GetMapping("/call/echo") + public String echo(@RequestParam("message") String message) { + return feignEchoService.echo(message); + } + } + + public static void main(String[] args) { + SpringApplication.run(SpringCloudRestClientBootstrap.class, args); + } +} diff --git a/spring-cloud-alibaba-examples/nacos-example/nacos-discovery-example/nacos-discovery-consumer-example/src/main/resources/application.properties b/spring-cloud-alibaba-examples/nacos-example/nacos-discovery-example/nacos-discovery-consumer-example/src/main/resources/application.properties index fbc9736e..1e6c2f5e 100644 --- a/spring-cloud-alibaba-examples/nacos-example/nacos-discovery-example/nacos-discovery-consumer-example/src/main/resources/application.properties +++ b/spring-cloud-alibaba-examples/nacos-example/nacos-discovery-example/nacos-discovery-consumer-example/src/main/resources/application.properties @@ -3,10 +3,5 @@ server.port=18083 management.endpoints.web.exposure.include=* spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848 -feign.sentinel.enabled=true +dubbo.registry.address= spring-cloud://nacos -spring.cloud.sentinel.transport.dashboard=localhost:8080 -spring.cloud.sentinel.eager=true - -spring.cloud.sentinel.datasource.ds1.file.file=classpath: flowrule.json -spring.cloud.sentinel.datasource.ds1.file.data-type=json \ No newline at end of file