微服务学习

一、微服务的定义

微服务是一种软件的架构风格,将单个应用程序开发为“一套小型服务”的方法,每个服务“运行在自己的进程中”,并通过轻量级机制(HTTP、RPC)进行通信

   单体应用架构  -> SOA(面向服务架构) -> 微服务

在这里插入图片描述

二、微服务的特点

  1. 传统单体架构的瓶颈
  • 模块功能的耦合性高
  • 更新需要全部代码重新编译
  • 扩展困难(高可用、弹性扩展)
  • 开发效率低
  • 技术栈需要统一
  1. 微服务的优势
  • 服务解耦
  • 高可用、弹性扩容
  • 高效开发
  • 多技术栈共用
  1. 微服务的功能组件
  • 注册中心
    存放和调度服务,去中心化 (服务注册、服务发现)
  • 负载均衡
    服务的弹性扩展
  • 网关
    微服务的对外隔离
  • 熔断
    预防服务雪崩、提高容错性
  • 内部服务调用
    内部服务间的接口调用
  • 配置中心
    统一的服务配置管理
    在这里插入图片描述
    在这里插入图片描述

常用的微服务框架:
SpringCloud 、 Dubbo
SpringCloud -Al
SpringCloid -T

三、SpringCloud

  • 注册中心(Eureka、Nacos)
  • 负载均衡 (Ribbon)
  • 网关 (Zuul、gateway)
  • 熔断、限流、降级 (Sentinel)
  • 内部服务调用 (OpenFeign)
  • 配置中心 (Config、Nacos)
  • 链路追踪(Sleuth)
  • 日志中心(ELK)

四、CAP原理

  • Consistency 一致性
    系统的数据信息(包括备份数据)在同一时刻都是一致的。
  • Availability 可用性
    服务在接收到客户端请求后,都能够给出响应
  • Partition Tolerance 分区一致性
    由于网络是不可靠的,所有节点之间很可能出现无法通讯的情况,在节点不能通信时,要保证系统可以继续正常服务

一个分布式系统中,CAP最多只能满足其中2个
在这里插入图片描述

CP AP CA

在这里插入图片描述

五、Eurek-Server(注册中心)

Spring Cloud Eureka是Spring Cloud Netflix微服务套件中实现服务治理的组件
满足AP

@EnableEurekaServer  开启注册中心,自动装配

配置文件

server:
  port: XXXX

eureka:
  instance:
    hostname: localhost   # 主机实例名
  client:
    register-with-eureka: false
    fetch-registry: false
    service-url:
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
  server:
    peer-node-read-timeout-ms: 3000
    enable-self-preservation: false   # 是否开启自我保护 
    eviction-interval-timer-in-ms: 60000

主要配置说明

1. server
  • 是否允许开启自我保护模式,默认 true
    当Eureka服务器在短时间内丢失过多客户端时,自我保护模式可使服务端不再删除失去连接的客户端
eureka.server.enable-self-preservation = false
  • 节点读取的超时时间 毫秒
eureka.server.peer-node-read-timeout-ms 
  • 节点连接的超时时间 毫秒
eureka.server.peer-node-connect-timeout-ms
  • 节点剔除的频率 毫秒
eureka.server.peer-node-connect-timeout-ms
  • 总节点数
eureka.server.peer-node-total-connections
2. client
  • Eureka服务器的地址,类型为HashMap,缺省的Key为 defaultZone;缺省的Value为 http://localhost:8761/eureka
eureka.client.service-url.defaultZone

如果服务注册中心为高可用集群时,多个注册中心地址以逗号分隔

  • 是否可以自己注册自己 默认true
eureka.client.register-with-eureka = false
  • 是否从注册中心拉取信息 默认true ,如果单节点不需要拉取
eureka.client.fetch-registry = false
3. instance
  • 服务名
spring.application.name
  • 主机实例名
eureka.instance.appname

六、Eureka-Client

配置文件

server:
  port: XXXX

eureka:
  instance:
    prefer-ip-address: true
    ip-address: XXX.XXXX.XX.XX
  client:
    service-url:
      defaultZone: http://localhost:XXXX/eureka/

spring:
  application:
    name: XXX-client

七、OpenFeign (Rest Http 框架)

HTTP 形式的 Rest API 提供了非常简洁高效的 类RPC的 调用方式

  • @EnableFeignClients 开启feign,自动装配
<!--引入feign依赖-->
 <dependency>
     <groupId>org.springframework.cloud</groupId>
     <artifactId>spring-cloud-starter-openfeign</artifactId>
 </dependency>
  • ribbon的超时时间
ribbon:
  ReadTimeout: 30000
  ConnectTimeout: 30000
  MaxAutoRetries: 0
  MaxAutoRetriesNextServer: 0
  OkToRetryOnAllOperations: false
  • 内部服务调用
    @FeignClient(“XXX-client”)
  • 外部服务调用
    @FeignClient(name=“XXX”,url=“XXX-client”)

@Autowired
private RestTemplate restTemplate;

  • 其他
    配置文件格式
    properties、yml、xml

bootstrap.yml 程序引导时执行
application 优先级低于bootstarp

// pom.xml
<dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-bootstrap</artifactId>
     <version>3.1.3</version>
</dependency>

八、网关(zuul、gateway)

Zuul-Server
  • 重定向
  • 负载均衡 ribon
  • 请求过滤

@EnableZuulProxy 开启网关

@RestController
@RequestMapping("base")

@GetMapping("info")

localhost:6001/base/info
http://localhsot:6002/api/user/base/info
http://localhsot:6002/user-client/base/info

  • 配置文件
zuul:
  routes:
    user-client: /api/user/**
    order-client: /api/order/**
    notify-client: /api/dispatch/**
  ignored-patterns: 
    - /*-client/**

server:
  port: 6060

eureka:
  instance:
    prefer-ip-address: true
  client:
    serviceUrl:
      defaultZone: http://10.70.70.34:6010/eureka/
      
spring:
  application:
    name: zuul-server
    
  servlet:
    multipart:
      enabled: true
      max-file-size: 10MB
      max-request-size: 10MB
  http:
    multipart:
      enabled: true
      max-file-size: 10MB
      max-request-size: 10MB
      
ribbon:
  ReadTimeout: 120000  #请求处理的超时时间
  ConnectTimeout: 30000  #请求连接的超时时间

hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 30000

过滤器

public class XXXFilter extends ZuulFilter{
   /**
     * 判断过滤器是否生效
     * @return
     */
    @Override
    public boolean shouldFilter() {
        RequestContext requestContext = RequestContext.getCurrentContext();
        HttpServletRequest request = requestContext.getRequest();
        String URI = request.getRequestURI();
        if (URI.indexOf("/api") > -1 ){
            return false;
        }
        return true;
    }
    
   /**
     * 拦截后的业务逻辑
     * @return
     * @throws ZuulException
     */
    @Override
    public Object run() throws ZuulException {
    }
}
<dependency>
   <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.9.0</version>
</dependency>

public static String createJWT(String id, String issuer, long ttlMillis,String KEY) throws Exception {

        // 指定签名的时候使用的签名算法,也就是header那部分,jjwt已经将这部分内容封装好了。
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;

        // 生成JWT的时间
        long nowMillis = System.currentTimeMillis();
        Date now = new Date(nowMillis);

        // 创建payload的私有声明(根据特定的业务需要添加,如果要拿这个做验证,一般是需要和jwt的接收方提前沟通好验证方式的)
        // 创建payload的私有声明(根据特定的业务需要添加,如果要拿这个做验证,一般是需要和jwt的接收方提前沟通好验证方式的)
        Map<String, Object> claims = new HashMap<>();
        claims.put("userid", "1267702530830254080");
        claims.put("trancom", "11110001");
        claims.put("name", "XXXXX");

        // 生成签名的时候使用的秘钥secret,切记这个秘钥不能外露哦。它就是你服务端的私钥,在任何场景都不应该流露出去。
        // 一旦客户端得知这个secret, 那就意味着客户端是可以自我签发jwt了。
        SecretKey keys = generalKey(KEY);

        // 下面就是在为payload添加各种标准声明和私有声明了
        JwtBuilder builder = Jwts.builder() // 这里其实就是new一个JwtBuilder,设置jwt的body
                .setClaims(claims)          // 如果有私有声明,一定要先设置这个自己创建的私有的声明,这个是给builder的claim赋值,一旦写在标准的声明赋值之后,就是覆盖了那些标准的声明的
                .setId(id)                  // 设置jti(JWT ID):是JWT的唯一标识,根据业务需要,这个可以设置为一个不重复的值,主要用来作为一次性token,从而回避重放攻击。
                .setIssuedAt(now)           // iat: jwt的签发时间
                .setIssuer(issuer)          // issuer:jwt签发人
                //.setSubject(subject)        // sub(Subject):代表这个JWT的主体,即它的所有人,这个是一个json格式的字符串,可以存放什么userid,roldid之类的,作为什么用户的唯一标志。
                .signWith(signatureAlgorithm, keys); // 设置签名使用的签名算法和签名使用的秘钥

        // 设置过期时间
        if (ttlMillis >= 0) {
            long expMillis = nowMillis + ttlMillis;
            Date exp = new Date(expMillis);
            builder.setExpiration(exp);
        }
        return builder.compact();
    }

    /**
     * 解密jwt
     *
     * @param jwt
     * @return
     * @throws Exception
     */
    public static Claims parseJWT(String jwt,String KEY) throws Exception {
        SecretKey key = generalKey(KEY);  //签名秘钥,和生成的签名的秘钥一模一样
        Claims claims = Jwts.parser()  //得到DefaultJwtParser
                .setSigningKey(key)                 //设置签名的秘钥
                .parseClaimsJws(jwt).getBody();     //设置需要解析的jwt
        return claims;
    }
    
/**
     * 由字符串生成加密key
     *
     * @return
     */
    private static SecretKey generalKey(String KEY){
        byte[] encodedKey = Base64.decodeBase64(KEY);
        SecretKeySpec keys = new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");

        return keys;
    }

九、配置中心

spring-cloud-config
nacos
apollo

Config-Server
  • 统一配置

  • 简化运维

  • 快速切换配置、参数

  • git作为后端配置存储(gitlab、github、码云、腾讯工蜂)

  • 以版本控制系统作为文件系统的使用

  • 本地文件系统作为存储库

  • 使用jdbc作为后端存储库

  • redis作为后端存储库

  • 组合多环境存储库

@EnableConfigServer
server:
  port: 7301

spring:
  application:
    name: config-server
  cloud:
    config:
      server:
        git:
          uri: https://gitee.com/xxx/test.git
          searchPaths:
          username: xxx
          password: xxx
          default-label: master
          basedir: root/config_temp
          force-pull: true
      label: master

eureka:
  instance:
    prefer-ip-address: true
  client:
    serviceUrl:
      defaultZone: http://localhost:6001/eureka/

客户端

<dependency>
     <groupId>org.springframework.cloud</groupId>
     <artifactId>spring-cloud-starter-config</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-bootstrap</artifactId>
    <version>3.1.3</version>
 </dependency>
spring:
  cloud:
    config:
      uri: http://localhost:7301
      label: master
      profile: dev

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值