微服务配置

本贴最后更新于 1320 天前,其中的信息可能已经时移俗易

搭建微服务各项功能所需配置

Eureka 服务端

  • 依赖:

      		<dependency>
      	  	         <groupId>org.springframework.cloud</groupId>
      	  	         <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
      	</dependency>
    
      <dependencyManagement>
          <dependencies>
              <dependency>
                  <groupId>org.springframework.cloud</groupId>
                  <artifactId>spring-cloud-dependencies</artifactId>
                  <version>${spring-cloud.version}</version>
                  <type>pom</type>
                  <scope>import</scope>
              </dependency>
          </dependencies>
    	</dependencyManagement>
    
  • 注解:

    @EnableEurekaServer
    
  • 
    
    
    

Eureka 客户端

  • 依赖:

    org.springframework.cloud spring-cloud-starter-netflix-eureka-client
  • 注解 :

    @EnableEurekaClient
    

Ribbon,Hystrix,Feign 消费者端###

  • 依赖:

    <!-- TODO 重试机制 -->
    	<dependency>
    		<groupId>org.springframework.retry</groupId>
    		<artifactId>spring-retry</artifactId>
    </dependency>
    <!-- TODO Hystrix熔断器 -->
    <dependency>
    	<groupId>org.springframework.cloud</groupId>
    	<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
    </dependency>
    
    <!-- TODO Feign服务调用 -->
    <dependency>
    	<groupId>org.springframework.cloud</groupId>
    	<artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>
    
  • 添加注解:

    @EnableEurekaClient //开启Eureka客户端
    @EnableHystrix  //开启熔断器
    @EnableFeignClients //开启Feign远程调用服务
    

如果使用 Feign 技术,那么 Hystrix 不需要导包和加注解


Zuul 网关依赖

  • 依赖:

          <!-- TODO 重试机制 -->
     <dependency>
     		<groupId>org.springframework.retry</groupId>
     		<artifactId>spring-retry</artifactId>
     </dependency>
     <!-- TODO zuul网管依赖 -->
         <dependency>
             <groupId>org.springframework.cloud</groupId>
             <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
         </dependency>
          <!-- TODO Eureka的客户端依赖-->
          <dependency>
              <groupId>org.springframework.cloud</groupId>
              <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
          </dependency>
    
  • yml 配置文件:

    	server:
    	  port: 10400
    	spring:
    	  application:
    	    name: zuul-service
    	eureka:
    	  client:
    	    registry-fetch-interval-seconds: 5 # 获取服务列表的周期:5s
    	    service-url:
    	      defaultZone: http://127.0.0.1:10300/eureka
    	  instance:
    	    prefer-ip-address: true
    	    ip-address: 127.0.0.1
    	zuul:
    	  retryable: true # 开启重试机制
    	  # routes:
    		# user-service: # 这里是路由id,随意写
    		# path: /user-service/** # 这里是映射路径
    		# service-id: user-service # 指定服务名称         # 不用添加routes,就会自动匹配 映射Eureka注册中的服务
    	ribbon:
    	  ConnectTimeout: 250 # 连接超时时间(ms)
    	  ReadTimeout: 2000 # 通信超时时间(ms)
    	  OkToRetryOnAllOperations: true # 是否对所有操作重试
    	  MaxAutoRetriesNextServer: 2 # 同一服务不同实例的重试次数
    	  MaxAutoRetries: 1 # 同一实例的重试次数
    	hystrix:
    	   command:
    	    default:
    	      execution:
    	        isolation:
    	          thread:
    	            timeoutInMillisecond: 6000 # 熔断超时时长:6000ms
    	zuul:   # 解决zuulfilter 中header头部信息丢失问题
     	   sensitiveHeaders:
    
  • 如果使用 Zuul,就替换了 consumer 消费者。并且 Zuul 中集成了各种依赖

JWT 配置

单独配置:key 密钥写在 java 代码中

  • JWT 定义在 Zuul 网关中,用来拦截请求,处理请求权限。

  • 依赖:

    	<!-- TODO jwt鉴权依赖 -->
         <dependency>
             <groupId>io.jsonwebtoken</groupId>
             <artifactId>jjwt</artifactId>
         </dependency>
         <!-- https://mvnrepository.com/artifact/joda-time/joda-time -->
         <dependency>
             <groupId>joda-time</groupId>
             <artifactId>joda-time</artifactId>
         </dependency>
    
  • JWTUtil 工具类:

      	    /**
      	 * @ClassName: JwtHelper
      	 * @Description: token工具类
      	 * @author: yuanxinqi
      	 * @date: 2018/8/17 9:59
      	 * @version: V 2.0.0
      	 * @since: (jdk_1.8)
      	 */
      	public class JWTUtils {
          /**
           * 获取token中的参数
           *
           * @param token
           * @return
           */
          public static Claims parseToken(String token,String key) {
              if ("".equals(token)) {
                  return null;
              }
    
              try {
                  return Jwts.parser()
                          .setSigningKey(DatatypeConverter.parseBase64Binary(key))
                          .parseClaimsJws(token).getBody();
              } catch (Exception ex) {
                  return null;
              }
          }
    
          /**
           * 生成token
           *
           * @param userId
           * @return
           */
          public static String createToken(Integer userId,String username,String key, int expireMinutes) {
              SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
              //生成签名密钥
              byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary(key);
    
              Key signingKey = new SecretKeySpec(apiKeySecretBytes, signatureAlgorithm.getJcaName());
    
              //添加构成JWT的参数
              JwtBuilder builder = Jwts.builder()
      //                .setHeaderParam("type", "JWT")
      //                .setSubject(userId.toString())
                      .claim("userId", userId) // 设置载荷信息
                      .claim("username",username)
                      .claim("age",23)
                      .setExpiration(DateTime.now().plusMinutes(expireMinutes).toDate())// 设置超时时间
                      .signWith(signatureAlgorithm, signingKey);
    
              //生成JWT
              return builder.compact();
          }
      public static void main(String[] args) {
    
              String token = JWTUtils.createToken(1, "zhangsan","admin", 30);
              System.out.println(token);
    
              Claims claims = JWTUtils.parseToken(token, "admin");
    
              System.out.println(claims);
          }
      }
    

yml 文件中配置 key 密钥:

  • JWTUtils 工具类:

    /**
     * @ClassName: JwtHelper
     * @Description: token工具类
     * @author: yuanxinqi
     * @date: 2018/8/17 9:59
     * @version: V 2.0.0
     * @since: (jdk_1.8)
     */
    @ConfigurationProperties("jwt.config")
    public class JWTUtils {
    
        private String key;
    
        public String getKey() {
            return key;
        }
    
        public void setKey(String key) {
            this.key = key;
        }
    
        /**
         * 获取token中的参数
         *
         * @param token
         * @return
         */
        public Claims parseToken(String token) {
            if ("".equals(token)) {
                return null;
            }
    
            try {
                return Jwts.parser()
                        .setSigningKey(DatatypeConverter.parseBase64Binary(key))
                        .parseClaimsJws(token).getBody();
            } catch (Exception ex) {
                return null;
            }
        }
    
        /**
         * 生成token
         *
         * @param id
         * @return
         */
        public String createToken(String id ,String role , int expireMinutes) {
            SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
            //生成签名密钥
            byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary(key);
    
            Key signingKey = new SecretKeySpec(apiKeySecretBytes, signatureAlgorithm.getJcaName());
    
            //添加构成JWT的参数
            JwtBuilder builder = Jwts.builder()
    //                .setHeaderParam("type", "JWT")
    //                .setSubject(userId.toString())
                    .claim("id", id) // 设置载荷信息
                    .claim("role",role)
                    .setExpiration(DateTime.now().plusMinutes(expireMinutes).toDate())// 设置超时时间
                    .signWith(signatureAlgorithm, signingKey);
    
            //生成JWT
            return builder.compact();
        }
    }
    
  • 在需要调用 JWTUtils 的服务中配置文件 yml:

    jwt:
      config:
        key: tensquare
    
  • 在 application 启动类中进行注册:

    @Bean
    public JWTUtils jwtUtils(){
    	return new JWTUtils();
    }
    
  • 在 controller 中进行调用时,

    @Autowired
    private JWTUtils jwtUtils;
    

Zuul 中 token 过滤器配置

  • 在 Zuul 服务中,定义 JWTFilter 类,添加 @conponent 注解,继承 ZuulFilter,实现四个方法。
@Component
public class JWTFilter extends ZuulFilter {
    @Override
    public String filterType() {
        //TODO 返回pre 表示请求前进行 过滤
        // pre请求前   route路由请求时   post在route和error过滤器之后调用  error处理请求时发生错误时
        return "pre";
    }

    @Override
    public int filterOrder() {
        //TODO 顺序排名
        return 1;
    }

    @Override
    public boolean shouldFilter() {
        //TODO 是否执行
        return true;
    }

    @Override
    public Object run() throws ZuulException {
        RequestContext context = RequestContext.getCurrentContext();
        HttpServletRequest request = context.getRequest();
        String url = request.getRequestURL().toString();

        //发布和查看个人信息等,才进行拦截判断
        if (url.contains("/user/findByUsername") || url.contains("/user/uploadImg")
                || url.contains("/user/updatePassword") || url.contains("/user/updatePasswordBefore")){
            //进行拦截判断
            String token = request.getHeader("authorization");
            //解析
            Claims claims = JWTUtils.parseToken(token, "user");
            if (claims == null){
                // 10 拦截
                context.setSendZuulResponse(false);
                context.setResponseStatusCode(401);
                context.setResponseBody("{'msg':'校验失败'}");
                context.getResponse().setContentType("text/html;charset=utf-8");//  不设置的话,中文乱码
                return null;
            }
        }

        return null;
    }
}

zuul 中的熔断返回类

  • Zuul 中默认是开启了 熔断机制的。只需配置好 yml 中的重试机制。
  • 在 Zuul 服务中,添加熔断返回类,如果 Zuul 中发生熔断,就会返回 FallBack 中的值。
@Component
public class ZuulFallBack implements FallbackProvider {
    @Override
    public String getRoute() {
        return "*";
    }

    @Override
    public ClientHttpResponse fallbackResponse(String route, Throwable cause) {
        return new ClientHttpResponse() {
            @Override
            public HttpStatus getStatusCode() throws IOException {
                return HttpStatus.OK;
            }

            @Override
            public int getRawStatusCode() throws IOException {
                return this.getStatusCode().value();
            }

            @Override
            public String getStatusText() throws IOException {
                return this.getStatusCode().getReasonPhrase();
            }

            @Override
            public void close() {

            }

            @Override
            public InputStream getBody() throws IOException {
                //返回的内容,在此中书写
                return new ByteArrayInputStream("当前服务暂时不可用,喝杯咖啡冷静一下吧~~~".getBytes());
            }

            @Override
            public HttpHeaders getHeaders() {
                HttpHeaders headers = new HttpHeaders();
                MediaType mt = new MediaType("application", "json", Charset.forName("UTF-8"));
                headers.setContentType(mt);
                return headers;
            }
        };
    }
}
  • 微服务

    微服务架构是一种架构模式,它提倡将单一应用划分成一组小的服务。服务之间互相协调,互相配合,为用户提供最终价值。每个服务运行在独立的进程中。服务于服务之间才用轻量级的通信机制互相沟通。每个服务都围绕着具体业务构建,能够被独立的部署。

    96 引用 • 155 回帖
  • Java

    Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3168 引用 • 8207 回帖
  • Spring

    Spring 是一个开源框架,是于 2003 年兴起的一个轻量级的 Java 开发框架,由 Rod Johnson 在其著作《Expert One-On-One J2EE Development and Design》中阐述的部分理念和原型衍生而来。它是为了解决企业应用开发的复杂性而创建的。框架的主要优势之一就是其分层架构,分层架构允许使用者选择使用哪一个组件,同时为 JavaEE 应用程序开发提供集成的框架。

    941 引用 • 1458 回帖 • 151 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...