├── .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 | //}
--------------------------------------------------------------------------------