4

基于 Spring Cloud 的微服务脚手架 - Grey Zeng

 2 years ago
source link: https://www.cnblogs.com/greyzeng/p/16989946.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

基于 Spring Cloud 的微服务脚手架

作者: Grey

原文地址:

博客园:基于 Spring Cloud 的微服务脚手架

CSDN:基于 Spring Cloud 的微服务脚手架

本文主要介绍了基于 Spring Cloud Finchley 和 Spring Boot 2.0.x 版本的微服务脚手架的搭建和关键代码说明,参考了重新定义 Spring Cloud 实战

相关组件和版本

组件 版本 备注
Spring Boot 2.0.9.RELEASE -
Spring Cloud Finchley.SR4 -
JDK 1.8 高于JDK 1.8会有兼容性问题
Eureka 基于 Spring Cloud F 版 注册中心
Zuul 基于 Spring Cloud F 版 网关
hystrix 基于 Spring Cloud F 版 熔断器
Spring Cloud Config 基于 Spring Cloud F 版 配置中心
Spring Cloud OpenFeign 基于 Spring Cloud F 版 用于服务之间的通讯,使用 HTTP 协议

架构图如下

img

启动方式,按如下顺序启动

  • skeleton-eureka-server

  • skeleton-config-server

  • skeleton-zuul-server

  • skeleton-hystrix-dashboard

  • skeleton-user-service

  • skeleton-data-service

测试三个请求,需要带上x-customs-user参数,否则会被拦截器拦截提示无权限。

GET http://localhost:7777/sc-user-service/getProviderData
Accept: application/json
x-customs-user: Spring
HTTP/1.1 200 
Date: Sat, 17 Dec 2022 11:09:48 GMT
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked

[
  "Beijing Company",
  "Shanghai Company",
  "Shenzhen Company"
]
GET http://localhost:7777/sc-user-service/getContextUserId
Accept: application/json
x-customs-user: Spring
HTTP/1.1 200 
Date: Sat, 17 Dec 2022 11:09:29 GMT
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked

Spring
GET http://localhost:7777/sc-user-service/getDefaultUser
Accept: application/json
x-customs-user: Spring
HTTP/1.1 200 
Date: Sat, 17 Dec 2022 11:08:54 GMT
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked

zhudeming-dev

核心代码说明
上述三个方法在成功调用之前,都需要做鉴权逻辑

用户鉴权部分,实现HandlerInterceptor即可,在preHandle中处理鉴权逻辑


public class UserContextInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse respone, Object arg2) throws Exception {
        User user = new User(HttpConvertUtil.httpRequestToMap(request));
        if (StringUtils.isEmpty(user.getUserId()) && StringUtils.isEmpty(user.getUserName())) {
            log.error("the user is null, please access from gateway or check user info");
            return false;
        }
        UserContextHolder.set(user);
        return true;
    }
……
}

上述三个请求分别代表三种不同的逻辑处理方式,第一个请求首先是到 sc-user-service 服务,sc-user-service 通过 RestTemplate 方式直接调用 data-service 服务,核心代码如下


@Component
public class UserService implements IUserService {
  ……
    @Override
    public List<String> getProviderData() {
        List<String> result = restTemplate.getForObject("http://sc-data-service/getProviderData", List.class);
        return result;
    }
}

第二个方法getContextUserId是获取当前上下文用户,使用的是 Spring Cloud 自带的 Feign 客户端,请求 data-service,Feign 请求会被拦截,并把当前用户存在 ThreadLocal 中, data-service 从ThreadLocal 中拿到当前用户信息返回即可, 核心代码如下

public class UserContextInterceptor implements HandlerInterceptor {
    private static final Logger log = LoggerFactory.getLogger(UserContextInterceptor.class);

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse respone, Object arg2) throws Exception {
        User user = new User(HttpConvertUtil.httpRequestToMap(request));
        if (StringUtils.isEmpty(user.getUserId()) && StringUtils.isEmpty(user.getUserName())) {
            log.error("the user is null, please access from gateway or check user info");
            return false;
        }
        // 存当前用户
        UserContextHolder.set(user);
        return true;
    }
}

其中UserContextHolder.set(user)就是把当前用户存在ThreadLocal中。

public class UserContextHolder {
 
    public static ThreadLocal<User> context = new ThreadLocal<User>();

    public static User currentUser() {
        return context.get();
    }

    public static void set(User user) {
        context.set(user);
    }

    public static void shutdown() {
        context.remove();
    }

}

第三个方法getDefaultUser同样是 sc-user-service 通过 Feign 客户端访问 data-service,但是用户是通过配置中心来获取(即:skeleton-config-server 项目作用)

@Component
@ConfigurationProperties(prefix = "cn.springcloud.book")
public class DataConfig {

    private String defaultUser;

 public String getDefaultUser() {
  return defaultUser;
 }

 public void setDefaultUser(String defaultUser) {
  this.defaultUser = defaultUser;
 }
    
}
server:
  port: 9090
spring:
  cloud:
    config:
      server:
        git:
          uri: https://gitee.com/zhudeming/spring-cloud-config.git
          #username:
          #password:
          search-paths: SC-BOOK-CONFIG
  application:
    name: sc-configserver

代码地址#

microservice-skeleton, tag: finchley.sr4

参考资料#

重新定义 Spring Cloud 实战


Recommend

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK