spring cloud 学习(一)—— 微服务实战演习笔记

微服务实战练习

  • 前言
    • 1、基本工具
    • 3、 注册中心
      • 基于NetflixEureKa做了二次封装
    • 4、微服务的拆分
      • 如何拆分“功能”:
      • 服务和数据关系:
    • 5、应用间通信方式
      • 5.1 应用间的通信方式:
      • 5.2 Spring Cloud ——RestTemplate
      • 5.3负载均衡-Ribbon
      • 5.4 应用间通信
      • 5.5 项目多模块改造
      • 5.6 同步与异步
    • 6 统一配置中心
      • 6.1 统一配置中心
      • 6.2 config server
      • 6.3 config client
      • 6.4 配置的动态刷新,自动配置
      • 6.5 SpringCLoud Bus
    • 7 异步和消息
      • 7.1 异步和消息
      • 7.2 RabbitMQ 的基本使用
      • 7.3 Spring cloud Stream
      • 7.4 Spring cloud Stream 使用下
    • 8 网关服务和Zuul
      • 8.1 基本介绍
      • 8.2 路由转发、排除和自定义
      • 8.3 Cookie 与动态路由
      • 8.4 路由和高可用
    • 9、Zuul 的过滤器和综合利用
      • 9.1 Pre和Post 过滤器
      • 9.2 Zuul 限流
      • 9.3 Zuul 的权限校验
      • 9.4 模拟登录功能实现:登录 , token, redis,
      • 9.5 权限设置
      • 9.6 完成权限设置校验下
      • 9.7 跨域
    • 服务器容错
    • 10.1 服务容错和Hystrix
      • 10.2 触发降级
      • 10.3 超时设置:
      • 10.4 探讨断路器模式
      • 10.5 使用配置项
      • 10.6 feign-hystrix 使用
      • 10.7 hystrix-dashboard
      • 10.8 Zuul 超时
    • 11 服务追踪
      • 11.1 服务追踪(上)
      • 11.2 服务追踪(下)
    • 12 容器部署
    • 13 升级

前言

官网:https://spring.io/projects/spring-cloud-openfeign#learn
技能基础:Spring boot, Linux, Docker

1、基本工具

  • Config:
  • Ribbon:
  • Zuul:
  • Hystrix:
  • EureKa:
  • 容器编排和服务追踪 : docker + RANCHER、 spring CLoud Sleuth + ZIPKIN

##2、 微服务与单体架构

  • 单体架构:开发效率低,代码维护难, 部署不灵活,稳定性不高, 扩展性不够
  • 微服务:服务注册发现,服务网关, 后端通用服务, 前端服务(可以聚合和裁剪)

3、 注册中心

基于NetflixEureKa做了二次封装

EureKa Server
EureKa Client
1、 Eureka Server 高可用
2、总结:EnbleEurekaServer EnbleEurekaClient
心跳检测、健康检查、负载均衡等功能
Eureka 的高可用,建议两台以上

3、服务发现的用处
桥梁:最重要的基础部分注册中心,代理
客户端发现: Eureka
服务端发现(含有代理):Nginx, Zookeeper, Kubernetes

微服务的特点: 异构
SpringCloud的服务调用方式: REST or RPC ?, Node.js 的enureka-js-client

4、微服务的拆分

起点:既有架构的形态
不适合的:系统访问压力不大, 业务稳定,包含很多强事物场景
终点:进化
因素:
原则:

康威定律:沟通的问题会影响系统设置。
服务拆分的方法论:
扩展立方模型:Scale Cube : X 轴 水平复制, Z轴 数据分区, Y轴 功能分区

如何拆分“功能”:

(1) 单一职责、松耦合, 高内聚
(2) 关注点分离 : 按职责、 按通用性、 按粒度级别

服务和数据关系:

(1) 先业务后数据
(2)无状态服

5、应用间通信方式

5.1 应用间的通信方式:

HTTP、 RPC 对应的 Dubbo、 Spring Cloud。

5.2 Spring Cloud ——RestTemplate

例如:

// @Autowired
   //private LoadBalancerClient loadBalancerClient;

   @Autowired
   private  RestTemplate restTemplate;
   @GetMapping("/getProductMsg")
   public  String getProductMsg(){
       //1、第一种方式:(直接使用restTemplate, url 写死)
      /*
       RestTemplate  restTemplate = new RestTemplate (  );

       String response =  restTemplate.getForObject ( "http://localhost:8080/msg", String.class );
       log.info("response = {}", response);
       */
       //2、第二种方式(利用loadBalancerClient通过应用名获取url)
      /* ServiceInstance serviceInstance =  loadBalancerClient.choose (  "PRODUCT");
       String url = String.format ( "http://%s:%s",serviceInstance.getHost (), serviceInstance.getPort ()) + "/msg";
       RestTemplate  restTemplate = new RestTemplate (  );

       String response =  restTemplate.getForObject ( "http://localhost:8080/msg", String.class );*/

      //3、第三种方式(利用注解@LoadBalanced,可在restTemplate里使用应用名字)
      String response =  restTemplate.getForObject ( "http://PRODUCT/msg", String.class );

       log.info("response = {}", response);
       return  response;
   }

5.3负载均衡-Ribbon

客户端负载均衡器: Ribbon
(RestTemplate Feign Zuul)

Ribbon:
(1)过程: 服务发现、 服务选择规则、 服务监听
(2)包含组件:ServerList, IRule, ServerListFilter

5.4 应用间通信

Feign:
声明是REST客户端(伪RPC)
采用了基于接口的注解

5.5 项目多模块改造

模块命名:
XXX-server 所有业务逻辑
XXX-client 对外暴露的接口
XXX-common 公用的对象(可以被内外部使用)

5.6 同步与异步

消息中间件:
中间件的选择: RabbitMQ、 Kafa、 ActiveMQ

6 统一配置中心

6.1 统一配置中心

以往的缺陷:不方便维护、 配置内容安全与权限, 更新配置项目需要重启。

方式: 远端git ——config-server ——本地git

6.2 config server

yml 文件命名规则:
/{name}-{profiles}.yml
/{label}/{name}-{profiles}.yml
其中: name 服务名 ,profiles 环境 label 分支

6.3 config client

配置文件加载过程:
bootstrap.yml 先加载
application.yml后加载

6.4 配置的动态刷新,自动配置

SpringCloud Bus
/bus-refresh
远端git ————————》 Config-server : ——》product, order
本地git

消息队列: RabbitMQ

6.5 SpringCLoud Bus

(1)加入 依赖
(2)改配置
(3)加注解 :

@RefreshScope

7 异步和消息

7.1 异步和消息

常见形态: 通知 、 请求/异步响应、 消息

MQ 应用场景: 异步处理、 流量削峰(如: 秒杀活动)、日志处理(卡夫卡)、应用解耦

RabbitMQ 的基本使用
自动创建对象

7.2 RabbitMQ 的基本使用

接收方(client)

package com.imooc.order.message;

import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

@Slf4j
@Component
public class MqReceiver {
    // 1、@RabbitListener(queues = "myQueue")
    // 2、自动创建
    // @RabbitListener(queuesToDeclare = @Queue("myQueue"))
    //3、 自动创建 exchange 和queue 绑定
    @RabbitListener(bindings = @QueueBinding ( value =  @Queue( "myQueue"), exchange = @Exchange("myExchange")))
    public  void process(String  message){
        log.info ("MqReceiver:{}", message);
    }

    /**
     * 数码供应商
     * @param message
     */
    @RabbitListener(bindings = @QueueBinding (  exchange = @Exchange("myOrder"), key ="computer", value =  @Queue( "computerOrder")))
    public  void processComputer(String  message){
        log.info ("computer  MqReceiver:{}", message);
    }


    /**
     * 水果供应商
     * @param message
     */
    @RabbitListener(bindings = @QueueBinding (  exchange = @Exchange("myOrder"), key ="fruit", value =  @Queue( "fruitOrder")))
    public  void processFruit(String  message){
        log.info ("fruit  MqReceiver:{}", message);
    }
}

发送方(server)

package com.imooc.order;

import org.junit.Test;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Date;

@Component
public class MqSenderTest extends OrderApplicationTests {

    @Autowired
    private AmqpTemplate amqpTemplate;

    @Test
    public void send() {
        amqpTemplate.convertAndSend("myQueue", "now " + new Date());
    }

    @Test
    public void sendOrder() {
        amqpTemplate.convertAndSend("myOrder", "computer", "now " + new Date());
    }
}

7.3 Spring cloud Stream

单个实例
多个实例: 分组

7.4 Spring cloud Stream 使用下

rabbitMQ 查看消息堆积

8 网关服务和Zuul

8.1 基本介绍

服务网关的要素:稳定性、高可用、 安全性, 性能并发性, 扩展性
常见的网关方案:Ngnix+ Lua、 Kong、Tyk、SpringCloud Zuul

  • 路由+ 过滤器 = Zuul
  • 核心:一系列过滤器

Zuul 四种过滤器API:前置(Pre)、 后置(Post)、 路由(Route)、 错误(Error)
spring cloud 学习(一)—— 微服务实战演习笔记_第1张图片

8.2 路由转发、排除和自定义

spring cloud 学习(一)—— 微服务实战演习笔记_第2张图片
1、 端口冲突,修改一下服务器端口号即可
spring cloud 学习(一)—— 微服务实战演习笔记_第3张图片
2 、自定义路由:
把服务的路由定义为myProduct
spring cloud 学习(一)—— 微服务实战演习笔记_第4张图片
查看路由规则
spring cloud 学习(一)—— 微服务实战演习笔记_第5张图片
3、排除某些路由
spring cloud 学习(一)—— 微服务实战演习笔记_第6张图片

8.3 Cookie 与动态路由

Cookie 自动忽略,可以设置
动态路由配置

8.4 路由和高可用

前置(pre): 限流 鉴权 参数校验
后置(Post): 统计 日志

Zuul 的高可用: 多个节点注册到Eureka Server, Nginx和 Zuul"混搭"

9、Zuul 的过滤器和综合利用

spring cloud 学习(一)—— 微服务实战演习笔记_第7张图片

9.1 Pre和Post 过滤器

token 过滤
http头

9.2 Zuul 限流

时机: 请求被转发之前调用
令牌桶限流
spring cloud 学习(一)—— 微服务实战演习笔记_第8张图片
限流案例:link

9.3 Zuul 的权限校验

cookie 里设置openid
可能出席因为版本不同导致客户端连接不上服务
解决:在pom文件添加如下:

 

            org.springframework.boot

            spring-boot-starter-web

        

9.4 模拟登录功能实现:登录 , token, redis,

9.5 权限设置

9.6 完成权限设置校验下

优化
在前置过滤器中实现相关逻辑
分布式Session Vs OAuth2

9.7 跨域

@CrossOrigin(allowCredentials = "true")//  允许带cookie的跨域

服务器容错

10.1 服务容错和Hystrix

雪崩效应: 牵一发而动全身

防雪崩利器:基于Netflix对应的Hystrix——> HyStrix
HyStrix:
(1)服务降级: 优先核心服务、 非核心服务不可用或弱可用,
通过HystrixCommand注解指定、 fallbackMethod(回退函数)中具体实现降级逻辑
(2) 服务熔断:
(3) 依赖隔离:
(4) 监控(HystrixDashboard):

10.2 触发降级

降级应用场景:服务停止 、 内部抛异常
demo:

package com.imooc.order.controller;

import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.Arrays;

@RestController
public class HystrixController {

    @HystrixCommand(fallbackMethod = "fallback")
    @GetMapping("/getProductInfoList")
    public  String getProductInfoList(){
        RestTemplate restTemplate = new RestTemplate ();
        return restTemplate.postForObject ("http://127.0.0.1:8001/product/listForOrder",
                Arrays.asList ("157875196366160022"),
                String.class);
       //throw  new RuntimeException ("发生异常了");
    }


    private  String  fallback(){
        return  "太拥挤了,请稍候再试~~";
    }
} 

10.3 超时设置:

@HystrixCommand(commandProperties = {@HystrixProperty (name = "execution.isolation.thread.timeoutInMilliseconds", value = "3000")}

完整示例如下:

package com.imooc.order.controller;

import com.netflix.hystrix.contrib.javanica.annotation.DefaultProperties;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.Arrays;

@RestController
@DefaultProperties(defaultFallback = "defaulFallback")
public class HystrixController {

    @HystrixCommand(commandProperties = {@HystrixProperty (name = "execution.isolation.thread.timeoutInMilliseconds", value = "3000")}) //超时时间设置
    @GetMapping("/getProductInfoList")
    public String getProductInfoList() {
        RestTemplate restTemplate = new RestTemplate ();
        return restTemplate.postForObject ("http://127.0.0.1:8001/product/listForOrder",
                Arrays.asList ("157875196366160022"),
                String.class);
        //throw  new RuntimeException ("发生异常了");
    }


    private String fallback() {
        return "太拥挤了,请稍候再试~~";
    }

    private String defaulFallback() {
        return "默认提示:太拥挤了,请稍候再试~~";
    }
}

10.4 探讨断路器模式

线程池隔离
Hystirx 自动实现了依赖隔离

@HystrixCommand(commandProperties = {
            @HystrixProperty (name = "circuitBreaker.enabled", value = "true"), //服务熔断
            @HystrixProperty (name="circuitBreaker.requestVolumeThreshold", value ="10" ),
            @HystrixProperty (name="circuitBreaker.sleepWindowInMilliseconds", value = "10000"), //休眠时间窗
            @HystrixProperty (name="circuitBreaker.errorThresholdPercentage", value = "60")})

断路器作用: 自我保护(类似于保险丝)
spring cloud 学习(一)—— 微服务实战演习笔记_第9张图片

10.5 使用配置项

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

10.6 feign-hystrix 使用

配置

feign:
  hystrix:
    enabled: true

10.7 hystrix-dashboard

10.8 Zuul 超时

本质上还是hystrix的超时配置
spring cloud 学习(一)—— 微服务实战演习笔记_第10张图片
启动效果如下:
spring cloud 学习(一)—— 微服务实战演习笔记_第11张图片

11 服务追踪

通常做法:日志

11.1 服务追踪(上)

链路监控:
Spring cloud sleuth 组件
链路追踪:zipkin工具, 配置

11.2 服务追踪(下)

集成步骤:引入依赖、启动ZipKin Server 、 配置参数

分布式追踪系统:
(1)核心步骤:数据存储, 数据查询, 展示
(2)OpenTracing 标准:来自CNCF, ZIPKN等
(3)Annotation:事件类型, CS,CR,SS,SR
spring cloud 学习(一)—— 微服务实战演习笔记_第12张图片
几个概念:traceId、 spanId, travelId

12 容器部署

-(1) docker
供参考的学习课程:第一个docker 化的java应用
-(2) rancher
为了更方便地管理docker
rancher 服务端放置于Linux 服务器
rancher 客户端放置于另一台服务器
镜像加速器

  • (3)环境部署
    生成镜像, Push镜像, rancher中加入镜像
  • (4)构建eureka 的高可用
    rancher 启动多个服务
    配置时
  • (5)构建api-gateway
    负载均衡
    负载均衡器

13 升级

GA:general availablility 面向大众的可用版本
M: milestone 里程碑版本
SNAPSHOT: 快照。代码可变

源码链接:github

你可能感兴趣的:(spring,cloud)