├── .gitignore ├── jeecg-boot-producer ├── src │ └── main │ │ ├── resources │ │ └── bootstrap.properties │ │ └── java │ │ └── org │ │ └── jeecg │ │ └── NacosProviderDemoApplication.java ├── doc │ ├── application.properties │ └── NACOSCONFIG │ │ └── jeecgtest-nacos-config.properties └── pom.xml ├── jeecg-boot-customer ├── src │ └── main │ │ ├── resources │ │ └── application.properties │ │ └── java │ │ └── org │ │ └── jeecg │ │ ├── cloud │ │ ├── control │ │ │ ├── HelloController.java │ │ │ └── NacosController.java │ │ └── service │ │ │ └── EchoService.java │ │ └── NacosConsumerApplication.java └── pom.xml ├── jeecg-boot-security ├── src │ └── main │ │ ├── resources │ │ └── application.yml │ │ └── java │ │ └── org │ │ └── jeecg │ │ └── auth │ │ ├── controller │ │ └── UserController.java │ │ ├── JeecgSecurityApplication.java │ │ ├── config │ │ ├── MyPasswordEncoder.java │ │ ├── SpringSecurityConfig.java │ │ └── MyUserDetailsService.java │ │ └── handler │ │ ├── MyAuthenctiationSuccessHandler.java │ │ └── MyAuthenctiationFailureHandler.java └── pom.xml ├── jeecg-boot-monitor ├── src │ └── main │ │ ├── resources │ │ └── application.yml │ │ └── java │ │ └── org │ │ └── jeecg │ │ └── SpringbootAdminApplication.java └── pom.xml ├── jeecg-boot-gateway ├── doc │ └── application.properties ├── src │ └── main │ │ ├── resources │ │ └── application.yml │ │ └── java │ │ └── org │ │ └── jeecg │ │ ├── DemoGatewayApplication.java │ │ ├── filter │ │ └── GlobalAccessRequestFilter.java │ │ └── config │ │ └── DynamicRoutingConfig.java └── pom.xml ├── pom.xml └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | ## ide 2 | **/.idea 3 | *.iml 4 | .rebel.xml.bak 5 | rebel.xml 6 | 7 | ## backend 8 | **/target 9 | **/logs 10 | 11 | ## front 12 | **/*.lock 13 | -------------------------------------------------------------------------------- /jeecg-boot-producer/src/main/resources/bootstrap.properties: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangdaiscott/SpringCloudAll/HEAD/jeecg-boot-producer/src/main/resources/bootstrap.properties -------------------------------------------------------------------------------- /jeecg-boot-customer/src/main/resources/application.properties: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangdaiscott/SpringCloudAll/HEAD/jeecg-boot-customer/src/main/resources/application.properties -------------------------------------------------------------------------------- /jeecg-boot-producer/doc/application.properties: -------------------------------------------------------------------------------- 1 | server.port=8081 2 | spring.application.name=nacos-provider 3 | spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848 4 | management.endpoints.web.exposure.include=* -------------------------------------------------------------------------------- /jeecg-boot-security/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 9111 3 | spring: 4 | application: 5 | name: jeecg-security 6 | # 服务端点检查 7 | management: 8 | endpoints: 9 | web: 10 | exposure: 11 | include: '*' -------------------------------------------------------------------------------- /jeecg-boot-monitor/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 9112 3 | spring: 4 | application: 5 | name: jeecg-monitor 6 | cloud: 7 | nacos: 8 | discovery: 9 | server-addr: 127.0.0.1:8848 10 | # 服务端点检查 11 | management: 12 | endpoints: 13 | web: 14 | exposure: 15 | include: '*' -------------------------------------------------------------------------------- /jeecg-boot-producer/doc/NACOSCONFIG/jeecgtest-nacos-config.properties: -------------------------------------------------------------------------------- 1 | server.port=8061 2 | spring.application.name=nacos-provider 3 | spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848 4 | management.endpoints.web.exposure.include=* 5 | spring.cloud.sentinel.transport.port=8719 6 | spring.cloud.sentinel.transport.dashboard=localhost:8080 7 | user.name=nacos-config-yaml 8 | user.age=68 -------------------------------------------------------------------------------- /jeecg-boot-gateway/doc/application.properties: -------------------------------------------------------------------------------- 1 | server.port=8000 2 | spring.application.name=jeecg-gateway 3 | spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848 4 | spring.cloud.gateway.routes[0].id=nacos-route 5 | spring.cloud.gateway.routes[0].uri=lb://nacos-provider 6 | spring.cloud.gateway.routes[0].predicates[0].name=Path 7 | spring.cloud.gateway.routes[0].predicates[0].args[pattern]=/nacos/** 8 | spring.cloud.gateway.routes[0].filters[0]=StripPrefix=1 -------------------------------------------------------------------------------- /jeecg-boot-security/src/main/java/org/jeecg/auth/controller/UserController.java: -------------------------------------------------------------------------------- 1 | package org.jeecg.auth.controller; 2 | 3 | import org.springframework.web.bind.annotation.GetMapping; 4 | import org.springframework.web.bind.annotation.RequestMapping; 5 | import org.springframework.web.bind.annotation.RestController; 6 | 7 | @RestController 8 | @RequestMapping("/user") 9 | public class UserController { 10 | @GetMapping 11 | public String getUsers() { 12 | return "Hello Jeecg Spring Security"; 13 | } 14 | } -------------------------------------------------------------------------------- /jeecg-boot-security/src/main/java/org/jeecg/auth/JeecgSecurityApplication.java: -------------------------------------------------------------------------------- 1 | package org.jeecg.auth; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | /** 7 | * @Description: TODO 8 | * @author: scott 9 | * @date: 2020年05月23日 19:13 10 | */ 11 | @SpringBootApplication 12 | public class JeecgSecurityApplication { 13 | public static void main(String[] args) { 14 | SpringApplication.run(JeecgSecurityApplication.class, args); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /jeecg-boot-security/src/main/java/org/jeecg/auth/config/MyPasswordEncoder.java: -------------------------------------------------------------------------------- 1 | package org.jeecg.auth.config; 2 | 3 | import org.springframework.context.annotation.Bean; 4 | import org.springframework.security.crypto.password.PasswordEncoder; 5 | import org.springframework.stereotype.Component; 6 | 7 | @Component 8 | public class MyPasswordEncoder implements PasswordEncoder { 9 | @Override 10 | public String encode(CharSequence charSequence) { 11 | return charSequence.toString(); 12 | } 13 | 14 | @Override 15 | public boolean matches(CharSequence charSequence, String s) { 16 | return s.equals(charSequence.toString()); 17 | } 18 | } -------------------------------------------------------------------------------- /jeecg-boot-customer/src/main/java/org/jeecg/cloud/control/HelloController.java: -------------------------------------------------------------------------------- 1 | package org.jeecg.cloud.control; 2 | 3 | import org.jeecg.cloud.service.EchoService; 4 | import org.springframework.beans.factory.annotation.Autowired; 5 | import org.springframework.web.bind.annotation.GetMapping; 6 | import org.springframework.web.bind.annotation.RequestMapping; 7 | import org.springframework.web.bind.annotation.RestController; 8 | 9 | @RestController 10 | @RequestMapping("/cust") 11 | public class HelloController { 12 | @Autowired 13 | private EchoService ecService; 14 | 15 | @RequestMapping("/hello") 16 | public String index() { 17 | return "Greetings from Spring Boot!"; 18 | } 19 | 20 | } -------------------------------------------------------------------------------- /jeecg-boot-monitor/src/main/java/org/jeecg/SpringbootAdminApplication.java: -------------------------------------------------------------------------------- 1 | package org.jeecg; 2 | 3 | import de.codecentric.boot.admin.server.config.EnableAdminServer; 4 | import org.springframework.boot.SpringApplication; 5 | import org.springframework.boot.autoconfigure.SpringBootApplication; 6 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 7 | 8 | /** 9 | * @Description: TODO 10 | * @author: scott 11 | * @date: 2020年05月17日 18:25 12 | */ 13 | @SpringBootApplication 14 | @EnableAdminServer 15 | public class SpringbootAdminApplication { 16 | public static void main(String[] args) { 17 | SpringApplication.run(SpringbootAdminApplication.class); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /jeecg-boot-gateway/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 9999 3 | spring: 4 | application: 5 | name: jeecg-gateway 6 | cloud: 7 | nacos: 8 | discovery: 9 | server-addr: 127.0.0.1:8848 10 | gateway: 11 | discovery: 12 | locator: 13 | enabled: true 14 | routes: 15 | #nacos 16 | - id: nacos-route-produer 17 | uri: lb://nacos-provider 18 | predicates: 19 | - Path=/echo/**,/test/**,/sys/** 20 | - id: nacos-route-customer 21 | uri: lb://nacos-jeecg-customer 22 | predicates: 23 | - Path=/cust/** 24 | # #path Unused nacos 25 | # - id: path_route 26 | # uri: http://localhost:8001 27 | # predicates: 28 | # - Path=/echo/** 29 | # 服务端点检查 30 | management: 31 | endpoints: 32 | web: 33 | exposure: 34 | include: '*' -------------------------------------------------------------------------------- /jeecg-boot-security/src/main/java/org/jeecg/auth/config/SpringSecurityConfig.java: -------------------------------------------------------------------------------- 1 | package org.jeecg.auth.config; 2 | 3 | import org.springframework.context.annotation.Configuration; 4 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 5 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; 6 | 7 | @Configuration 8 | public class SpringSecurityConfig extends WebSecurityConfigurerAdapter { 9 | 10 | @Override 11 | protected void configure(HttpSecurity http) throws Exception { 12 | http.formLogin() // 定义当需要用户登录时候,转到的登录页面。 13 | .loginProcessingUrl("/user/login") // 自定义的登录接口 14 | .and() 15 | .authorizeRequests() // 定义哪些URL需要被保护、哪些不需要被保护 16 | .anyRequest() // 任何请求,登录后可以访问 17 | .authenticated(); 18 | } 19 | } -------------------------------------------------------------------------------- /jeecg-boot-customer/src/main/java/org/jeecg/NacosConsumerApplication.java: -------------------------------------------------------------------------------- 1 | package org.jeecg; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 6 | import org.springframework.cloud.openfeign.EnableFeignClients; 7 | import org.springframework.context.annotation.Bean; 8 | import org.springframework.web.client.RestTemplate; 9 | 10 | @SpringBootApplication 11 | @EnableDiscoveryClient 12 | @EnableFeignClients 13 | public class NacosConsumerApplication { 14 | 15 | //Instantiate RestTemplate Instance 16 | @Bean 17 | public RestTemplate restTemplate() { 18 | return new RestTemplate(); 19 | } 20 | 21 | public static void main(String[] args) { 22 | SpringApplication.run(NacosConsumerApplication.class, args); 23 | } 24 | } -------------------------------------------------------------------------------- /jeecg-boot-security/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | jeecg-boot-cloud-study 7 | com.jeecg.cloud 8 | 1.0.0 9 | 10 | 4.0.0 11 | 12 | jeecg-boot-security 13 | 14 | 15 | 16 | org.springframework.boot 17 | spring-boot-starter-web 18 | 19 | 20 | org.springframework.boot 21 | spring-boot-starter-security 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /jeecg-boot-customer/src/main/java/org/jeecg/cloud/service/EchoService.java: -------------------------------------------------------------------------------- 1 | package org.jeecg.cloud.service; 2 | 3 | import org.springframework.cloud.openfeign.FeignClient; 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.stereotype.Component; 6 | import org.springframework.web.bind.annotation.GetMapping; 7 | import org.springframework.web.bind.annotation.PathVariable; 8 | 9 | @FeignClient(name = "nacos-provider", fallback = EchoServiceFallback.class, configuration = FeignConfiguration.class) 10 | public interface EchoService { 11 | @GetMapping(value = "/echo/{str}") 12 | String echo(@PathVariable("str") String str); 13 | } 14 | 15 | @Component 16 | class EchoServiceFallback implements EchoService { 17 | @Override 18 | public String echo(@PathVariable("str") String str) { 19 | return "echo fallback"; 20 | } 21 | } 22 | 23 | class FeignConfiguration { 24 | @Bean 25 | public EchoServiceFallback echoServiceFallback() { 26 | return new EchoServiceFallback(); 27 | } 28 | } -------------------------------------------------------------------------------- /jeecg-boot-monitor/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | jeecg-boot-cloud-study 7 | com.jeecg.cloud 8 | 1.0.0 9 | 10 | 4.0.0 11 | 12 | jeecg-boot-monitor 13 | 14 | 15 | 16 | 17 | 18 | de.codecentric 19 | spring-boot-admin-starter-server 20 | 2.1.4 21 | 22 | 23 | com.alibaba.cloud 24 | spring-cloud-starter-alibaba-nacos-discovery 25 | 26 | 27 | -------------------------------------------------------------------------------- /jeecg-boot-gateway/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | jeecg-boot-cloud-study 7 | com.jeecg.cloud 8 | 1.0.0 9 | 10 | 4.0.0 11 | 12 | jeecg-boot-gateway 13 | 14 | 15 | 16 | 17 | org.springframework.cloud 18 | spring-cloud-starter-gateway 19 | 20 | 21 | org.springframework.cloud 22 | spring-cloud-starter-netflix-hystrix 23 | 24 | 25 | com.alibaba.cloud 26 | spring-cloud-starter-alibaba-nacos-discovery 27 | 28 | 29 | -------------------------------------------------------------------------------- /jeecg-boot-customer/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | jeecg-boot-cloud-study 7 | com.jeecg.cloud 8 | 1.0.0 9 | 10 | 4.0.0 11 | 12 | jeecg-boot-customer 13 | 14 | 15 | 16 | org.springframework.boot 17 | spring-boot-starter-web 18 | 19 | 20 | com.alibaba.cloud 21 | spring-cloud-starter-alibaba-nacos-discovery 22 | 23 | 24 | org.springframework.cloud 25 | spring-cloud-starter-openfeign 26 | 27 | 28 | com.alibaba.cloud 29 | spring-cloud-alibaba-sentinel 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /jeecg-boot-security/src/main/java/org/jeecg/auth/handler/MyAuthenctiationSuccessHandler.java: -------------------------------------------------------------------------------- 1 | package org.jeecg.auth.handler; 2 | 3 | import com.fasterxml.jackson.databind.ObjectMapper; 4 | import org.slf4j.Logger; 5 | import org.slf4j.LoggerFactory; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.security.core.Authentication; 8 | import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler; 9 | import org.springframework.stereotype.Component; 10 | 11 | import javax.servlet.ServletException; 12 | import javax.servlet.http.HttpServletRequest; 13 | import javax.servlet.http.HttpServletResponse; 14 | import java.io.IOException; 15 | 16 | /** 17 | * 登录成功的处理器 18 | */ 19 | @Component("myAuthenctiationSuccessHandler") 20 | public class MyAuthenctiationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler { 21 | 22 | private Logger logger = LoggerFactory.getLogger(getClass()); 23 | 24 | @Autowired 25 | private ObjectMapper objectMapper; 26 | 27 | @Override 28 | public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, 29 | Authentication authentication) throws IOException, ServletException { 30 | 31 | logger.info("登录成功"); 32 | 33 | response.setContentType("application/json;charset=UTF-8"); 34 | response.getWriter().write(objectMapper.writeValueAsString(authentication)); 35 | } 36 | } -------------------------------------------------------------------------------- /jeecg-boot-producer/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | jeecg-boot-cloud-study 7 | com.jeecg.cloud 8 | 1.0.0 9 | 10 | 4.0.0 11 | 12 | jeecg-boot-producer 13 | 14 | 15 | 19 | 20 | org.springframework.boot 21 | spring-boot-starter-web 22 | 23 | 24 | com.alibaba.cloud 25 | spring-cloud-starter-alibaba-nacos-discovery 26 | 27 | 28 | com.alibaba.cloud 29 | spring-cloud-starter-alibaba-nacos-config 30 | 31 | 32 | com.alibaba.cloud 33 | spring-cloud-starter-alibaba-sentinel 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /jeecg-boot-security/src/main/java/org/jeecg/auth/config/MyUserDetailsService.java: -------------------------------------------------------------------------------- 1 | package org.jeecg.auth.config; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.cache.Cache; 7 | import org.springframework.security.core.authority.AuthorityUtils; 8 | import org.springframework.security.core.userdetails.User; 9 | import org.springframework.security.core.userdetails.UserDetails; 10 | import org.springframework.security.core.userdetails.UserDetailsService; 11 | import org.springframework.security.core.userdetails.UsernameNotFoundException; 12 | import org.springframework.security.crypto.factory.PasswordEncoderFactories; 13 | import org.springframework.security.crypto.password.PasswordEncoder; 14 | import org.springframework.stereotype.Component; 15 | import sun.security.util.SecurityConstants; 16 | 17 | @Component 18 | public class MyUserDetailsService implements UserDetailsService { 19 | private Logger logger = LoggerFactory.getLogger(getClass()); 20 | 21 | @Autowired 22 | private PasswordEncoder passwordEncoder; 23 | 24 | @Override 25 | public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { 26 | logger.info("用户的用户名: {}", username); 27 | // TODO 根据用户名,查找到对应的密码,与权限 28 | 29 | // 封装用户信息,并返回。参数分别是:用户名,密码,用户权限 30 | User user = new User(username, passwordEncoder.encode("123456"), AuthorityUtils.commaSeparatedStringToAuthorityList("admin")); 31 | return user; 32 | } 33 | } -------------------------------------------------------------------------------- /jeecg-boot-security/src/main/java/org/jeecg/auth/handler/MyAuthenctiationFailureHandler.java: -------------------------------------------------------------------------------- 1 | package org.jeecg.auth.handler; 2 | 3 | import com.fasterxml.jackson.databind.ObjectMapper; 4 | import org.slf4j.Logger; 5 | import org.slf4j.LoggerFactory; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.http.HttpStatus; 8 | import org.springframework.security.core.AuthenticationException; 9 | import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler; 10 | import org.springframework.stereotype.Component; 11 | 12 | import javax.servlet.ServletException; 13 | import javax.servlet.http.HttpServletRequest; 14 | import javax.servlet.http.HttpServletResponse; 15 | import java.io.IOException; 16 | 17 | /** 18 | * 登录失败的处理器 19 | */ 20 | @Component("myAuthenctiationFailureHandler") 21 | public class MyAuthenctiationFailureHandler extends SimpleUrlAuthenticationFailureHandler { 22 | 23 | private Logger logger = LoggerFactory.getLogger(getClass()); 24 | 25 | @Autowired 26 | private ObjectMapper objectMapper; 27 | 28 | @Override 29 | public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, 30 | AuthenticationException exception) throws IOException, ServletException { 31 | 32 | logger.info("登录失败"); 33 | 34 | response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value()); 35 | response.setContentType("application/json;charset=UTF-8"); 36 | response.getWriter().write("fail"); 37 | } 38 | } -------------------------------------------------------------------------------- /jeecg-boot-customer/src/main/java/org/jeecg/cloud/control/NacosController.java: -------------------------------------------------------------------------------- 1 | package org.jeecg.cloud.control; 2 | 3 | import org.jeecg.cloud.service.EchoService; 4 | import org.springframework.beans.factory.annotation.Autowired; 5 | import org.springframework.beans.factory.annotation.Value; 6 | import org.springframework.cloud.client.ServiceInstance; 7 | import org.springframework.cloud.client.loadbalancer.LoadBalancerClient; 8 | import org.springframework.web.bind.annotation.GetMapping; 9 | import org.springframework.web.bind.annotation.RequestMapping; 10 | import org.springframework.web.bind.annotation.RestController; 11 | import org.springframework.web.client.RestTemplate; 12 | 13 | @RestController 14 | @RequestMapping("/cust") 15 | public class NacosController { 16 | 17 | @Autowired 18 | private LoadBalancerClient loadBalancerClient; 19 | @Autowired 20 | private RestTemplate restTemplate; 21 | @Autowired 22 | private EchoService ecService; 23 | 24 | @Value("${spring.application.name}") 25 | private String appName; 26 | 27 | @GetMapping("/echo/restTemplate") 28 | public String echoAppName() { 29 | //Access through the combination of LoadBalanceClient and RestTemplate 30 | ServiceInstance serviceInstance = loadBalancerClient.choose("nacos-provider"); 31 | String path = String.format("http://%s:%s/echo/%s", serviceInstance.getHost(), serviceInstance.getPort(), appName); 32 | System.out.println("request path:" + path); 33 | return restTemplate.getForObject(path, String.class); 34 | } 35 | 36 | @GetMapping("/echo/feign") 37 | public String echoAppName2() { 38 | return ecService.echo("appName2"); 39 | } 40 | 41 | 42 | } -------------------------------------------------------------------------------- /jeecg-boot-producer/src/main/java/org/jeecg/NacosProviderDemoApplication.java: -------------------------------------------------------------------------------- 1 | package org.jeecg; 2 | import com.alibaba.csp.sentinel.annotation.SentinelResource; 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 6 | import org.springframework.context.ConfigurableApplicationContext; 7 | import org.springframework.web.bind.annotation.GetMapping; 8 | import org.springframework.web.bind.annotation.PathVariable; 9 | import org.springframework.web.bind.annotation.RestController; 10 | 11 | @SpringBootApplication 12 | @EnableDiscoveryClient 13 | public class NacosProviderDemoApplication { 14 | 15 | /** 16 | * 启动端口 17 | */ 18 | private static String host; 19 | 20 | public static void main(String[] args) { 21 | ConfigurableApplicationContext applicationContext = SpringApplication.run(NacosProviderDemoApplication.class, args); 22 | // while(true) { 23 | String userName = applicationContext.getEnvironment().getProperty("user.name"); 24 | String userAge = applicationContext.getEnvironment().getProperty("user.age"); 25 | host = applicationContext.getEnvironment().getProperty("server.port"); 26 | System.err.println("user name :" +userName+"; age: "+userAge+"; host: "+host); 27 | // } 28 | } 29 | 30 | @RestController 31 | public class EchoController { 32 | @GetMapping(value = "/echo/{string}") 33 | @SentinelResource("echo") 34 | public String echo(@PathVariable String string) { 35 | return "Hello Nacos Discovery " + string+" ,host:"+host; 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /jeecg-boot-gateway/src/main/java/org/jeecg/DemoGatewayApplication.java: -------------------------------------------------------------------------------- 1 | package org.jeecg; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 6 | import org.springframework.cloud.gateway.route.RouteLocator; 7 | import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder; 8 | import org.springframework.context.annotation.Bean; 9 | 10 | @SpringBootApplication 11 | @EnableDiscoveryClient 12 | public class DemoGatewayApplication { 13 | 14 | public static void main(String[] args) { 15 | SpringApplication.run(DemoGatewayApplication.class, args); 16 | } 17 | 18 | @Bean 19 | public RouteLocator customRouteLocator(RouteLocatorBuilder builder) { 20 | return builder.routes() 21 | .route("path_route", r -> r.path("/get") 22 | .uri("http://httpbin.org")) 23 | .route("baidu_path_route", r -> r.path("/baidu") 24 | .uri("https://news.baidu.com/guonei")) 25 | .route("host_route", r -> r.host("*.myhost.org") 26 | .uri("http://httpbin.org")) 27 | .route("rewrite_route", r -> r.host("*.rewrite.org") 28 | .filters(f -> f.rewritePath("/foo/(?.*)", "/${segment}")) 29 | .uri("http://httpbin.org")) 30 | .route("hystrix_route", r -> r.host("*.hystrix.org") 31 | .filters(f -> f.hystrix(c -> c.setName("slowcmd"))) 32 | .uri("http://httpbin.org")) 33 | .route("hystrix_fallback_route", r -> r.host("*.hystrixfallback.org") 34 | .filters(f -> f.hystrix(c -> c.setName("slowcmd").setFallbackUri("forward:/hystrixfallback"))) 35 | .uri("http://httpbin.org")) 36 | // .route("limit_route", r -> r 37 | // .host("*.limited.org").and().path("/anything/**") 38 | // .filters(f -> f.requestRateLimiter(c -> c.setRateLimiter(redisRateLimiter()))) 39 | // .uri("http://httpbin.org")) 40 | .build(); 41 | } 42 | 43 | } -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | com.jeecg.cloud 7 | jeecg-boot-cloud-study 8 | pom 9 | 1.0.0 10 | 11 | 12 | 13 | aliyun 14 | aliyun Repository 15 | http://maven.aliyun.com/nexus/content/groups/public 16 | 17 | false 18 | 19 | 20 | 21 | 22 | 23 | org.springframework.boot 24 | spring-boot-starter-parent 25 | 2.1.3.RELEASE 26 | 27 | 28 | 29 | 30 | jeecg-boot-customer 31 | jeecg-boot-producer 32 | jeecg-boot-gateway 33 | jeecg-boot-monitor 34 | jeecg-boot-security 35 | 36 | 37 | 38 | 1.8 39 | 40 | 41 | 42 | 57 | 58 | org.springframework.boot 59 | spring-boot-starter-actuator 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | org.springframework.cloud 68 | spring-cloud-dependencies 69 | Greenwich.SR3 70 | pom 71 | import 72 | 73 | 74 | com.alibaba.cloud 75 | spring-cloud-alibaba-dependencies 76 | 2.1.0.RELEASE 77 | pom 78 | import 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | org.springframework.boot 87 | spring-boot-maven-plugin 88 | 89 | 90 | 91 | 92 | 93 | -------------------------------------------------------------------------------- /jeecg-boot-gateway/src/main/java/org/jeecg/filter/GlobalAccessRequestFilter.java: -------------------------------------------------------------------------------- 1 | package org.jeecg.filter; 2 | 3 | import org.springframework.cloud.gateway.filter.GatewayFilterChain; 4 | import org.springframework.cloud.gateway.filter.GlobalFilter; 5 | import org.springframework.core.Ordered; 6 | import org.springframework.core.io.buffer.DataBuffer; 7 | import org.springframework.http.HttpStatus; 8 | import org.springframework.http.server.reactive.ServerHttpRequest; 9 | import org.springframework.http.server.reactive.ServerHttpResponse; 10 | import org.springframework.stereotype.Component; 11 | import org.springframework.util.StringUtils; 12 | import org.springframework.web.server.ServerWebExchange; 13 | import reactor.core.publisher.Flux; 14 | import reactor.core.publisher.Mono; 15 | 16 | import java.nio.charset.StandardCharsets; 17 | import java.util.Arrays; 18 | import java.util.stream.Collectors; 19 | 20 | import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR; 21 | import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.addOriginalRequestUrl; 22 | 23 | @Component 24 | public class GlobalAccessRequestFilter implements GlobalFilter, Ordered { 25 | 26 | @Override 27 | public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) { 28 | //从请求头中取出token 29 | String token = exchange.getRequest().getHeaders().getFirst("Authorization"); 30 | //未携带token 31 | if (token == null || token.isEmpty()) { 32 | ServerHttpResponse originalResponse = exchange.getResponse(); 33 | originalResponse.setStatusCode(HttpStatus.OK); 34 | originalResponse.getHeaders().add("Content-Type", "application/json;charset=UTF-8"); 35 | byte[] response = "{\"code\": \"401\",\"msg\": \"401 Unauthorized.\"}".getBytes(StandardCharsets.UTF_8); 36 | DataBuffer buffer = originalResponse.bufferFactory().wrap(response); 37 | return originalResponse.writeWith(Flux.just(buffer)); 38 | } 39 | //取出token包含的身份 40 | String userName = token; 41 | if (userName.isEmpty()) { 42 | ServerHttpResponse originalResponse = exchange.getResponse(); 43 | originalResponse.setStatusCode(HttpStatus.OK); 44 | originalResponse.getHeaders().add("Content-Type", "application/json;charset=UTF-8"); 45 | byte[] response = "{\"code\": \"10002\",\"msg\": \"invalid token.\"}".getBytes(StandardCharsets.UTF_8); 46 | DataBuffer buffer = originalResponse.bufferFactory().wrap(response); 47 | return originalResponse.writeWith(Flux.just(buffer)); 48 | } 49 | 50 | // 2. 重写StripPrefix(获取真实的URL) 51 | addOriginalRequestUrl(exchange, exchange.getRequest().getURI()); 52 | String rawPath = exchange.getRequest().getURI().getRawPath(); 53 | String newPath = "/" + Arrays.stream(StringUtils.tokenizeToStringArray(rawPath, "/")).skip(1L).collect(Collectors.joining("/")); 54 | ServerHttpRequest newRequest = exchange.getRequest().mutate().path(newPath).build(); 55 | exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, newRequest.getURI()); 56 | 57 | //将现在的request,添加当前身份 58 | ServerHttpRequest mutableReq = exchange.getRequest().mutate().header("Authorization-UserName", userName).build(); 59 | ServerWebExchange mutableExchange = exchange.mutate().request(mutableReq).build(); 60 | return chain.filter(mutableExchange); 61 | } 62 | 63 | @Override 64 | public int getOrder() { 65 | return 0; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SpringCloudAll 2 | Spring Cloud Alibaba 解决方案 —— 学习示例代码 3 | 4 | ### 技术体系【知识点】 5 | 6 | 7 | - 1、Nacos 服务注册和发现 8 | - 2、Nacos 统一配置中心 9 | - 3、熔断降级限流 sentinel 10 | - 4、feign配合sentinel使用 11 | - 5、SpringCloud Gateway 12 | - 6、服务监控 actuator 13 | - 7、Spring Boot Admin服务监控 14 | - 8、链路跟踪 skywalking 15 | - 9、Spring Security集成 16 | - 10、Spring Security OAuth2集成 17 | - 11、rabitmq的环境搭建和使用 18 | - 12、maven多配置环境 19 | - 13、服务多实例运行 20 | - 14、分布定时任务 Quartz/XXL-JOB/elastic-job 21 | - 15、Seata分布式事务 22 | - 16、Spring Stream 23 | - 17、分布式文件系统 minio、阿里OSS 24 | 25 | ### 常用注解 26 | 27 | 注解 | 功能 | 位置 28 | -|-|- 29 | @EnableDiscoveryClient | 启动nacos服务注册发现| 启动类 | 30 | @EnableFeignClients | 启动 Feign| 启动类 | 31 | @FeignClient | 声明为Feign接口 | 接口类 | 32 | @EnableAdminServer| Spring Boot Admin Server监控服务端 | 启动类 | 33 | @SentinelRestTemplate| | 34 | 35 | 36 | ### 环境安装 37 | 软件 | 访问地址 | 账号 | 启动 38 | -|-|-|- 39 | [nacos安装](https://nacos.io/zh-cn/docs/quick-start-docker.html) | http://localhost:8848/nacos| nacos/nacos | docker启动容器 | 40 | [sentinel控制台](https://www.cnblogs.com/fx-blog/p/11720220.html) | http://localhost:8080 | sentinel/sentinel | 启动命令: java -jar sentinel-dashboard-1.6.3.jar `本地目录: D:\JAVA\alibaba-cloud`| 41 | 42 | 43 | ### 测试请求 44 | 45 | ``` xml 46 | # 服务端生产者接口(启动多实例) 47 | http://localhost:8061/echo/123 48 | http://localhost:8061/actuator | 服务端点检查 49 | http://localhost:8061/actuator/nacos-discovery | 服务端点检查 50 | ## 服务端_多实例测试 51 | http://localhost:8062/echo/123 [修改nacos配置端口,启动多实例] 52 | http://localhost:8063/echo/123 [修改nacos配置端口,启动多实例] 53 | 54 | 55 | # 客户端消费者接口 56 | http://localhost:8071/cust/echo/feign 57 | http://localhost:8071/cust/echo/restTemplate 58 | ## 客户端_多实例测试 59 | http://localhost:8072/cust/echo/feign [修改端口,启动多实例] 60 | http://localhost:8073/cust/echo/feign [修改端口,启动多实例] 61 | 62 | 63 | # Gateway(需传递 Head参数 => Authorization:{任意值}) 64 | http://localhost:9999/echo/22 65 | 66 | # SpringAdmin 67 | http://localhost:9112 68 | 69 | # Security 70 | http://localhost:9111/user 71 | (admin/123456) 72 | ``` 73 | 74 | 75 | 76 | 77 | ### 官方文档 78 | - [spring-cloud-alibaba](https://github.com/alibaba/spring-cloud-alibaba/blob/master/README-zh.md) 79 | - [spring-cloud-alibaba > html](https://spring-cloud-alibaba-group.github.io/github-pages/greenwich/spring-cloud-alibaba.html#_introduction_of_sentinel) 80 | - [spring-cloud-gateway](https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.2.RELEASE/reference/html/#the-path-route-predicate-factory) 81 | - [spring-security](https://docs.spring.io/spring-security/site/docs/current/reference/html5/#getting) 82 | - [spring-security-oauth](https://projects.spring.io/spring-security-oauth/docs/oauth2.html) 83 | - [Seata 分布式事务](https://seata.io/zh-cn/index.html) 84 | - [Spring Cloud Stream中文指导手册](https://m.wang1314.com/doc/webapp/topic/20971999.html) 85 | 86 | 87 | 88 | ### 参考文献 89 | - [微服务后,Swagger接口统一文档](https://blog.csdn.net/qq_31748587/article/details/102563155) 90 | - 谷歌JSON插件 JSON-Handle 91 | - [Spring Boot Admin服务监控](https://www.jianshu.com/p/1749f04105fb) 92 | - [Spring Boot Admin client不再需要](https://my.oschina.net/u/1428688/blog/3110948) 93 | - [Spring Boot Admin+Nacos从入门到上线](https://blog.csdn.net/qq_38496561/article/details/105945386) 94 | - [容器使用Undertow替换tomcat](https://blog.csdn.net/moshowgame/article/details/84985765) 95 | - [Seata分布式事务 整合 SpringCloud](https://seata.io/zh-cn/blog/integrate-seata-with-spring-cloud.html) 96 | - [Gateway 之限流操作 一](https://www.toutiao.com/i6729667803353186827) 97 | - [Gateway 之限流操作 二](https://blog.csdn.net/u010889990/article/details/81169328) 98 | - [Gateway 之限流操作 三](https://www.cnblogs.com/pu20065226/p/11426279.html) 99 | - [Gateway 实现降级攻略](https://blog.csdn.net/SuperBins/article/details/94732087) 100 | - [灰度发布名词解释](https://www.cnblogs.com/panchanggui/p/11634026.html) 101 | - [Nacos动态路由实现](https://www.cnblogs.com/zlt2000/p/11712943.html) 102 | 103 | 104 | 105 | 106 | 107 | ### 技巧与工具 108 | - [在线工具yml和属性互转](https://www.toyaml.com/index.html) 109 | - yml文件注意(禁用tab,用俩空格) 110 | - 谷歌JSON插件 JSON-Handle 111 | - gateway 支持服务名方式访问 112 | - sentinel 服务台可以不用 113 | - [IDEA如何启动多实例](https://blog.csdn.net/zhou520yue520/article/details/81167841) 114 | - [idea run dashboard](https://blog.csdn.net/m18633778874/article/details/82687389) 115 | - [idea的Git主干同步到分支](https://blog.csdn.net/weixin_40836179/article/details/87003899) -------------------------------------------------------------------------------- /jeecg-boot-gateway/src/main/java/org/jeecg/config/DynamicRoutingConfig.java: -------------------------------------------------------------------------------- 1 | //package org.jeecg.config; 2 | // 3 | //import com.alibaba.fastjson.JSON; 4 | //import com.alibaba.fastjson.JSONObject; 5 | //import com.alibaba.nacos.api.NacosFactory; 6 | //import com.alibaba.nacos.api.PropertyKeyConst; 7 | //import com.alibaba.nacos.api.config.ConfigService; 8 | //import com.alibaba.nacos.api.config.listener.Listener; 9 | //import com.alibaba.nacos.api.exception.NacosException; 10 | //import org.slf4j.Logger; 11 | //import org.slf4j.LoggerFactory; 12 | //import org.springframework.beans.factory.annotation.Autowired; 13 | //import org.springframework.cloud.gateway.event.RefreshRoutesEvent; 14 | //import org.springframework.cloud.gateway.filter.FilterDefinition; 15 | //import org.springframework.cloud.gateway.handler.predicate.PredicateDefinition; 16 | //import org.springframework.cloud.gateway.route.RouteDefinition; 17 | //import org.springframework.cloud.gateway.route.RouteDefinitionWriter; 18 | //import org.springframework.context.ApplicationEventPublisher; 19 | //import org.springframework.context.ApplicationEventPublisherAware; 20 | //import org.springframework.context.annotation.Bean; 21 | //import org.springframework.stereotype.Component; 22 | //import org.springframework.web.util.UriComponentsBuilder; 23 | //import reactor.core.publisher.Mono; 24 | // 25 | //import java.net.URI; 26 | //import java.util.ArrayList; 27 | //import java.util.List; 28 | //import java.util.Properties; 29 | //import java.util.concurrent.Executor; 30 | // 31 | //@Component 32 | //public class DynamicRoutingConfig implements ApplicationEventPublisherAware { 33 | // 34 | // private final Logger logger = LoggerFactory.getLogger(DynamicRoutingConfig.class); 35 | // 36 | // private static final String DATA_ID = "zuul-refresh-dev.json"; 37 | // private static final String Group = "DEFAULT_GROUP"; 38 | // 39 | // @Autowired 40 | // private RouteDefinitionWriter routeDefinitionWriter; 41 | // 42 | // private ApplicationEventPublisher applicationEventPublisher; 43 | // 44 | // @Bean 45 | // public void refreshRouting() throws NacosException { 46 | // Properties properties = new Properties(); 47 | // properties.put(PropertyKeyConst.SERVER_ADDR, "192.168.44.129:8848"); 48 | // properties.put(PropertyKeyConst.NAMESPACE, "8282c713-da90-486a-8438-2a5a212ef44f"); 49 | // ConfigService configService = NacosFactory.createConfigService(properties); 50 | // configService.addListener(DATA_ID, Group, new Listener() { 51 | // @Override 52 | // public Executor getExecutor() { 53 | // return null; 54 | // } 55 | // 56 | // @Override 57 | // public void receiveConfigInfo(String configInfo) { 58 | // logger.info(configInfo); 59 | // 60 | // boolean refreshGatewayRoute = JSONObject.parseObject(configInfo).getBoolean("refreshGatewayRoute"); 61 | // 62 | // if (refreshGatewayRoute) { 63 | // List list = JSON.parseArray(JSONObject.parseObject(configInfo).getString("routeList")).toJavaList(RouteEntity.class); 64 | // 65 | // for (RouteEntity route : list) { 66 | // update(assembleRouteDefinition(route)); 67 | // } 68 | // } else { 69 | // logger.info("路由未发生变更"); 70 | // } 71 | // 72 | // 73 | // } 74 | // }); 75 | // } 76 | // 77 | // @Override 78 | // public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) { 79 | // this.applicationEventPublisher = applicationEventPublisher; 80 | // } 81 | // 82 | // /** 83 | // * 路由更新 84 | // * @param routeDefinition 85 | // * @return 86 | // */ 87 | // public void update(RouteDefinition routeDefinition){ 88 | // 89 | // try { 90 | // this.routeDefinitionWriter.delete(Mono.just(routeDefinition.getId())); 91 | // logger.info("路由更新成功"); 92 | // }catch (Exception e){ 93 | // logger.error(e.getMessage(), e); 94 | // } 95 | // 96 | // try { 97 | // routeDefinitionWriter.save(Mono.just(routeDefinition)).subscribe(); 98 | // this.applicationEventPublisher.publishEvent(new RefreshRoutesEvent(this)); 99 | // logger.info("路由更新成功"); 100 | // }catch (Exception e){ 101 | // logger.error(e.getMessage(), e); 102 | // } 103 | // } 104 | // 105 | // public RouteDefinition assembleRouteDefinition(RouteEntity routeEntity) { 106 | // 107 | // RouteDefinition definition = new RouteDefinition(); 108 | // 109 | // // ID 110 | // definition.setId(routeEntity.getId()); 111 | // 112 | // // Predicates 113 | // List pdList = new ArrayList<>(); 114 | // for (PredicateEntity predicateEntity: routeEntity.getPredicates()) { 115 | // PredicateDefinition predicateDefinition = new PredicateDefinition(); 116 | // predicateDefinition.setArgs(predicateEntity.getArgs()); 117 | // predicateDefinition.setName(predicateEntity.getName()); 118 | // pdList.add(predicateDefinition); 119 | // } 120 | // definition.setPredicates(pdList); 121 | // 122 | // // Filters 123 | // List fdList = new ArrayList<>(); 124 | // for (FilterEntity filterEntity: routeEntity.getFilters()) { 125 | // FilterDefinition filterDefinition = new FilterDefinition(); 126 | // filterDefinition.setArgs(filterEntity.getArgs()); 127 | // filterDefinition.setName(filterEntity.getName()); 128 | // fdList.add(filterDefinition); 129 | // } 130 | // definition.setFilters(fdList); 131 | // 132 | // // URI 133 | // URI uri = UriComponentsBuilder.fromUriString(routeEntity.getUri()).build().toUri(); 134 | // definition.setUri(uri); 135 | // 136 | // return definition; 137 | // } 138 | //} --------------------------------------------------------------------------------