Skip to content

微服务与容器化

微服务与容器化 微服务与容器化

微服务架构

微服务介绍

  • 什么是微服务
    • 它是一种架构模式
    • 相比较单体架构,微服务架构更独立,能够单独更新和发布
    • 微服务里面的服务仅仅用于某一个特定的业务功能
  • 为什么需要微服务
    • 逻辑清晰
    • 快速迭代
    • 多语言灵活组合
  • 微服务中的DDD是什么
    • 领域驱动设计(Domain Driven Design,简称DDD) —— 真正决定软件复杂性的是设计方法
      • 作用
        1. 有助于知道我们确定系统边界
        2. 能够聚焦在系统核心元素上
        3. 帮助我们拆分系统
      • 常用概念
        • 领域
          1. 领域:领域是有范围界限的,也可以说是有边界的
          2. 核心域:核心域是业务系统的核心价值
          3. 通用子域:所有子域的消费者,提供着通用服务
          4. 支撑子域:专注与业务系统的某一项重要的业务
        • 界限上下文
          1. 理解:描述子
          2. 方式:领域 + 界限上下文
          3. 目的:不在于如何划分边界,而是在于如何控制边界
        • 领域模型
          1. 理解:领域模型是对我们软件系统中要解决问题的抽象表达
          2. 领域:反应的是我们业务上需要解决的问题
          3. 模型:我们针对该问题提出的解决方案
      • DDD域微服务四层架构
        DDD域微服务四层架构
        DDD域微服务四层架构
    • 还有个定律:康威定律(Conway's Law),通俗讲就是组织架构要和微服务的拆分对应
  • 微服务的设计原则
    • 要领域驱动设计,而不是数据驱动设计,也不是界面驱动设计。
      • 数据驱动设计:比如根据模块先设计数据库,然后再拆分数据库...
    • 要边界清晰的微服务,而不是泥球小单体
    • 要职能清晰分明,而不是什么都放的大箩筐
    • 要做自己能hold住的微服务,而不是过度拆分的微服务

Docker

  • 为什么需要Docker
    1. 软件更新发布及部署低效,过程繁琐且需要人工介入
    2. 环境一致性难以保证,不同环境之间迁移成本太高
    3. 构建容易分发简单
  • 应用场景
    1. 构建运行环境
    2. 微服务
    3. CI(持续集成) / CD(持续部署)
  • Docker安装
    • MacOS安装:http://desktop.docker.com/mac/main/amd64/Docker.dmg?utm_source=docker&utm_medium=webreferral&utm_campaign=dd-smartbutton&utm_location=module
    • Linux 安装:yum install -y docker
  • Docker的重要概念
    • 客户端Client:可运行docker指令
    • 服务器进程(Docker Daemon):管理镜像和容器
    • 镜像仓库:存储镜像的仓库
    • 架构图
      架构图
  • Docker常用命令
    • Docker仓库操作:pull, push
    • Docker镜像管理:images, rmi (删除镜像), build
    • Docker生命周期管理:run, start, stop, rm

go-micro 之 grpc 和 ProtoBuf

  • RPC和gRPC介绍

    • RPC(好处:简单、通用、安全、高效)
      1. RPC代指远程过程调用(Remote Procedure Call)
      2. 包含了传输协议和编码(对象序列号)协议
      3. 允许运行于一台计算机的程序调用另一台计算机的子程序
    • gRPC()
      1. gRPC是一个高性能、开源、通用的RPC框架
      2. 基于HTTP2.0协议标准设计开发
      3. 支持多种语言,默认采用Protocol Buffer数据序列化协议
    • gRPC基本调用流程解析
      简要流程
      简要流程
      概述流程
      概述流程
  • ProtoBuf及详细语法介绍

    • ProtoBuf介绍
      1. 是一种轻便高效的序列化结构化数据的协议
      2. 通常是用在存储数据和需要远程数据通信的程序上
      3. 跨语言、更小(相比json xml等)、更快、更简单
    • 为什么使用ProtoBuf
      1. 加速站点之间数据传输速度
      2. 解决数据传输不规范问题
    • ProtoBuf常用概念
      1. Message定义:描述了一个请求或响应的消息格式
        • Message中字段修饰符
          • singular:表示成员有0个或者1个,一般省略不写
          • repeated:表示该字段可以包含0~N个元素
      2. 字段标识:消息的定义中,每个字段都有一个唯一的数值标签
      3. 常用数据类型:double、float、int32/64、bool、string、bytes
      4. Service服务定义:在Service中可以定义一个RPC服务接口
    • proto示例
      syntax = "proto3";                  /* 版本号 */
      
      package go.micro.service.product;   /* 包名 */
      
      service Product {                   /* 定义的服务 */
          rpc AddProduct(ProductInfo) returns (ResponseProduct) {}
      }
      
      message ProductInfo {               /* 消息格式 */
          // id = 字段标识符,一般不超过15
          int64  id = 1;
          string product_name = 2;
      }
      
      message ResponseProduct {
          int64 product_id = 1;
      }
      

go-micro 组件架构及通讯原理

  • Micro是什么
    1. 是用来构建和管理分布式程序的系统
    2. Runtime(运行时):用来管理配置,认证,网络等
      • Runtime(运行时)介绍
        1. 它是工具集,工具名称是 ‘micro’,在命令行使用
        2. 官方docker版本是 docker pull micro/micro
      • Runtime(运行时)组成
        1. api:api网关
        2. broker:允许一步消息的消息代理
        3. network:通过微网络服务构建多云网络
        4. new:服务模版生成器
        5. proxy:建立在 Go Micro 上的透明服务代理
        6. registry:一个服务资源管理器
        7. store:简单的状态存储
        8. web:web仪表板浏览服务
    3. Framework(程序开发框架):用来方便编写微服务,go-micro就是一个框架
      • Framework(go-micro)介绍
        1. 它是对分布式系统的高度抽象
        2. 提供分布式系统开发的核心库
        3. 可插拔的架构,按需使用
      • Framework(go-micro)组件
        1. 注册(Register):提供了服务发现机制
        2. 选择器(Selector):能够实现负载均衡
        3. 传输(Transport):服务与服务之间通信接口
        4. Broker:提供异步通信的消息发布/订阅接口
        5. 编码(Codec):消息传输到两端时进行编码与解码
        6. Server(服务端)、Client(客户端)
      • Framework(go-micro)组件架构图
        组件架构图
      • Framework(go-micro)通信图
        通信图
        Client通过selector去服务中心注册表进入服务发现,Server中的Register把开发完的服务注册到服务中心的注册表中。
    4. Clients(多语言客户端):支持多语言访问服务端

go-micro 案例编写

  • protoc 生成 rpc 服务
    syntax = "proto3";
    
    package go.micro.service.elasticnotes;
    option go_package = "./proto/jartin";
    service Jartin {
        rpc SayHello(SayRequest) returns (SayResponse) {}
    }
    
    message SayRequest {
        string message = 1;
    }
    
    message SayResponse {
        string answer = 1;
    }
    
    
    // bash
    // protoc --go_out=. --go-grpc_out=. ./proto/jartin/elasticnotes.proto
    
  • 编写server端

    package main
    
    import (
        "fmt"
        "github.com/micro/go-micro/v2"
        "newmicro/proto/jartin"
    )
    
    // 实现接口的结构体
    type JartinServer struct {
    }
    
    // 需要实现的方法
    func (c *JartinServer) SayHello(ctx context.Context, req *SayRequest, res *SayResponse) error {
        res.Answer = "输出结果,服务连接成功!"
    }
    
    func main() {
        // 创建新服务
        service := micro.NewService(
            micro.Name("jartin.elasticnotes.server"),
        )
        // 初始化方法
        service.Init()
        // 注册服务
        jartin.RegisterJartinServer(service.Server(), new())
        // 运行服务
        if err := service.Run(); err != nil {
            fmt.Println(err)
        }
    
    }
    

  • 编写Client端

    package main
    
    import (
        "context"
        "fmt"
        "github.com/micro/go-micro/v2"
        "newmicro/proto/jartin"
    )
    
    func main() {
        // 实例化
        service := micro.NewService(
            micro.Name("jartin.elasticnotes.client"),
        )
        // 初始化
        service.Init()
        //
        jar := jartin.JartinServer("jartin.elasticnotes.server", service.Client())
        res, err := jar.SayHello(context.TODO(), &jartin.SayRequest{Message: "接收到了"})
        if err != nil {
            fmt.Println(err)
        }
    }