精华内容
下载资源
问答
  • #Microservices这是用于使用SpringBoot玩微服务的沙盒
  • 微服务基础:TaskManager任务管理器 操作手册 产品说明 1.1. 产品功能 Task Manager 是一款代办事项管理软件;能够协助用户完成待办事务的管理与进度跟踪,比如工作计划、生日提醒、旅行安排等,以便更好地规划时间...

    来源https://developer.aliyun.com/adc/series/javastart/
    微服务基础:TaskManager任务管理器
    操作手册

    1. 产品说明
      1.1. 产品功能

    Task Manager 是一款代办事项管理软件;能够协助用户完成待办事务的管理与进度跟踪,比如工作计划、生日提醒、旅行安排等,以便更好地规划时间和安排生活。
    1.2. 通过本案例你将学习到

    如何使用 MSE 微服务引擎,实现服务的注册于发现;
    如何使用 Apache Dubbo 实现微服务的 RPC 调用;
    如何使用 HTTP 协议暴露微服务,并通过 Feign 实现调用。
    

    1.3. 应用&架构说明

    该产品共有 2 个应用,分别是:Web 客户端、服务端; 应用间,通过“MSE 微服务引擎”提供的 Nacos 引擎实现服务的注册于发现。
    

    1.3.1. Web 客户端

    为用户提供 Web 操作页面,包含浏览器端运行的 UI 逻辑,以及与之相关的控制层逻辑;
    使用微服务技术和服务端进行通信:“任务服务”使用 Apache Dubbo 客户端进行调用;“任务分类”服务,使用 Feign 实现远程调用.
    

    1.3.2. 服务端

    提供任务管理的各领域服务能力;

    持久化层:内嵌一套 H2 内存数据库实现数据存储能力(每次重启后数据会被重置);
    服务层:对外暴露 Apache Dubbo 和 HTTP 两种协议接口,其中“任务”相关的服务使用 Apache Dubbo 协议暴露,“任务分类”相关服务以 HTTP 协议暴露。
    

    架构图:
    在这里插入图片描述

    1. 部署&访问流程

      该示例项目无需任何修改,可以直接部署运行; 每个应用,部署成功后,最多可连续运行 30min 的时间,超时后系统会自动回收相关运行资源。

    2.1. 服务端部署

    在 "应用列表" 页签下点击"开发"按钮, 进入 Web IDE;
    在 Web IDE 中, 点击 "运维" 进入运维页面;
    在 Web IDE 中, 点击 "部署" 按钮, 确认部署信息,点击 "继续部署" 按钮,开始部署流程;
    等待部署完成, 此时在Web IDE 的终端会输出"云开发应用部署成功!";
    返回 "应用列表", 点击对应应用的 "访问" 按钮, 打开新窗口访问应用;
    用户名|密码, 都输入 sa , 点击 "connect" 进入控制台。
    

    2.2. 客户端部署

    在 "应用列表" 页签下点击"开发"按钮, 进入 Web IDE;
    在 Web IDE 中, 点击 "运维" 进入运维页面;
    在 Web IDE 中, 点击 "部署" 按钮, 确认部署信息,点击 "继续部署" 按钮,开始部署流程;
    等待部署完成, 此时在 Web IDE 的终端会输出"云开发应用部署成功!";
    返回 "应用列表", 点击对应应用的 "访问" 按钮, 打开新窗口访问应用;
    打开的新窗口即为任务管理的 Web 端。
    
    展开全文
  • java微服务开发(基础环境篇) 我们的目标是~~_浩瀚的宇宙 _~~全栈开发 俗话说的好 _工欲善其事 必先利其器 _对于一个开发者来说 一个好的开发环境可以带来的收益是巨大的 本篇的重点主要是linux上一的一些环境的安装...

    java微服务开发(基础环境篇)

    我们的目标是~~_浩瀚的宇宙 _~~全栈开发
    俗话说的好 _工欲善其事 必先利其器 _对于一个开发者来说 一个好的开发环境可以带来的收益是巨大的
    本篇的重点主要是linux上一的一些环境的安装 主要是docker

    本篇涉及到的是一些开发时候使用到的环境包括Windows环境和Linux环境

    Windows环境

    我的日常开发环境就是Windows 虽然大伙都推荐程序员使用mac 但是没办法 _咱们也没有闲钱啊 _ 所以一个正常的Windows开发环境就非常重要了

    Windows版本建议使用Windows10或者Windows7
    推荐:Windows10 下载安装地址:链接
    内存: 推荐内存16G
    不会现在还有人用4g内存的Windows10开发微服务吧 不会吧 不会吧

    基础环境配置

    基础环境没啥好说的 jdk你的会安装配置吧 不管是Windows还是Linux
    git的基本使用你得会用吧
    现在都是spring boot项目了 maven要会使吧,到处copy jar包到resources spring的几个jar不兼容 maven都可以解决这些难题

    Windows基础环境配置主要是jdk,git,maven

    jdk

    jdk可是Java程序员的命根子了 入门和他打交道 到达架构师级别 也要和他打交道 面试会问jvm 工作要依赖他跑项目 我愿称之为java程序员的一生之敌

    jdk是开发Java必备的环境 推荐为jdk1.8及其以上
    下载地址:Oracle官网地址:链接 我分享的百度云网盘地址:链接   提取码:9fkc

    下载后默认安装

    配置环境变量: 百度
    不会还有人觉得我会在这里详细写安装jdk和配置环境变量吧

    git

    git也是工作中常用的工具了,不管你的项目是大还是小 我都建议使用git来管理 并且找一个稳定的git仓库来保存
    比如国外的github 国内的gitee 也可以自建gitlab 或者gogs

    GIT(分布式版本控制系统)
    是一个开源的分布式版本控制系统,可以有效、高速地处理从很小到非常大的项目版本管理。
    下载地址: 链接

    下载后默认安装

    maven

    maven啊 通俗一点就是一个管理jar包的工具 让你可以不用手动的去copy jar 管理各个版本的jar包
    比如spring4下.的jar 和spring5.x的jar肯定是有兼容问题的 可以通过maven方便的管理 只要给出jar的坐标就可以了

    maven是现在主流的项目构建工具,但是目前spring正在淡化maven 转而推荐gradle
    Maven项目对象模型(POM),可以通过一小段描述信息来管理项目的构建,报告和文档的项目管理工具软件
    maven官网地址: 链接

    下载地址: 链接
    配置: 链接
    配置maven的中央仓库地址
    编辑maven_home/config/settings.xml
    找到 
    在最后添加如下xml代码

         <mirror>
          <id>alimaven</id>
          <name>aliyun maven</name>
          <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
          <mirrorOf>central</mirrorOf>        
         </mirror>
    

    配置localRepository (本地仓库存放地址 即为存放jar包和坐标的地址)
    编辑maven_home/config/settings.xml
    找到settings
    在下面添加如下代码 (这里的E:\repo为E盘下的repo文件夹 如果没有 请提前创建 可替换成自己的文件夹)

      <localRepository>E:\repo</localRepository>
    

    验证maven安装

    C:\Users\Administrator>mvn -v
    Apache Maven 3.6.3 (cecedd343002696d0abb50b32b541b8a6ba2883f)
    Maven home: D:\maven-3.6.3\bin\..
    Java version: 11.0.2, vendor: Oracle Corporation, runtime: D:\jdk
    Default locale: zh_CN, platform encoding: GBK
    OS name: "windows 10", version: "10.0", arch: "amd64", family: "windows"
    

    开发工具配置

    开发工具为日常开发中我使用到的一些开发工具

    IDEA

    IDEA 和 eclipse都是比较常用的java开发ide 在我刚学习的时候我就使用的是eclipse 在后来的某一次使用过IDEA后就很少打开eclipse了

    IDEA是我推荐使用的Java开发的IDE也是我正在使用的主力IDE
    官网地址: 链接
    下载地址: 链接
    如何激活 以及其他快捷配置 请问百度: 链接

    下载后默认安装
    配置IDEA 主要配置maven
    打开-File-Settings

    ![](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9jZG4ubmxhcmsuY29tL3l1cXVlLzAvMjAyMC9qcGVnLzE2OTcxMjcvMTU5NDM2NDkyNTEwMi0wZDRjZmQzYy01OWQ4LTRjYTktYjk1YS1lMDZmYTVmMGM0YjIuanBlZw?x-oss-process=image/format,png#align=left&display=inline&height=575&margin=[object Object]&originHeight=575&originWidth=1025&size=0&status=done&style=none&width=1025)

    Visual Studio Code

    vs code是微软出的一个ide 目前我也就使用它开发过前端 开发Java我觉得还是idea好

    vs code是一个基本上还算是全能的ide了 但是我还是觉得用来开发前端 html vue比较方便
    visual studio code官网: 链接

    下载地址: 链接
    配置vs code

    主要在扩展中启用如下扩展

    ![image.png](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9jZG4ubmxhcmsuY29tL3l1cXVlLzAvMjAyMC9wbmcvMTY5NzEyNy8xNTk0MzY1NTY4NjkzLTI2YjczMTQ3LTI5YmMtNGFjNC1iZDU1LTUyNjI1NWY0M2U4OS5wbmc?x-oss-process=image/format,png#align=left&display=inline&height=524&margin=[object Object]&name=image.png&originHeight=524&originWidth=392&size=57244&status=done&style=none&width=392)

    XShell

    xshell是目前主流的ssh链接工具 (主要是Free for Home xshell中一个窗口不能超过4个链接Xftp中不能超过2个)
    官网: 链接

    下载地址: 链接
    下载完成后默认安装

    Navicat Premium 12

    Navicat Premium 12是一款数据库可视化工具 可以用于管理mysql,postgre,oracle,sqlite,sqlserver,mariadb,mongondb链接
    官网: 链接

    下载地址: 链接
    下载完成后解压默认安装

    PDMan

    PDMan是一款开源免费的数据库模型建模工具,支持Windows,Mac,Linux等操作系统,是PowerDesigner之外,更好的免费的替代方案。他具有颜值高,使用简单的特点。包含数据库建模,灵活自动的自动生成代码模板,自动生成文档等多种开发人员实用的功能。

    下载地址: 链接
    下载完成后默认安装

    AnotherRedisDesktopManager

    Redis桌面管理器 - 是一个用于Windows,Linux和MacOS的快速开源Redis数据库管理应用程序。

    官网地址: 链接
    下载地址: 链接
    下载完成后默认安装

    Postman

    Postman是一款功能强大的网页调试与发送网页HTTP请求的软件

    官网地址: 链接
    下载地址: 链接
    下载完成后解压默认安装


    Linux环境

    作为一个开发人员 肯定要对Linux环境比较熟悉才行 其实Linux对于开发人员来说 说要掌握的命令并不是很多 日常的命令+一些中间件的操作命令一般就够了

    Linux环境对Linux的发行版本没有具体要求 只要不是太老的一般都可以 后面的中间件都是运行在docker上面
    Linux的发行版本太多了 我这里推荐 Centos7+ Ubuntu16+ 我使用的是centos7.7

    基础环境配置

    本次演示使用centos7作为演示
    centos7下载地址: 链接

    安装Linux

    下载上面提供的镜像
    在VMware里的前置安装请百度: 地址
    建议cpu: 4核 内存: 8G

    启动虚拟机后选择install centos 7
    ![image.png](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9jZG4ubmxhcmsuY29tL3l1cXVlLzAvMjAyMC9wbmcvMTY5NzEyNy8xNTk0MzY3Mjc1OTUxLTlhZTJkNTEwLWU5OTktNDlkNC1iMjI4LTUzYzliNTU0NTZmZS5wbmc?x-oss-process=image/format,png#align=left&display=inline&height=573&margin=[object Object]&name=image.png&originHeight=573&originWidth=821&size=34064&status=done&style=none&width=821)
    语言直接默认 点击continue
    ![image.png](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9jZG4ubmxhcmsuY29tL3l1cXVlLzAvMjAyMC9wbmcvMTY5NzEyNy8xNTk0MzY3MzIyMDkwLTg5ZThlZDIzLWI3MGMtNDQ3Mi1hMDRiLTk2YzAxMzQ4ZThiNi5wbmc?x-oss-process=image/format,png#align=left&display=inline&height=583&margin=[object Object]&name=image.png&originHeight=583&originWidth=801&size=126793&status=done&style=none&width=801)

    配置网络

    等待一会后点击NETWORK & HOSTNAME
    ![image.png](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9jZG4ubmxhcmsuY29tL3l1cXVlLzAvMjAyMC9wbmcvMTY5NzEyNy8xNTk0MzY3MzY4MjYyLTU4MmRhYWVmLWFmMjMtNDJhYi05OTQ0LWU1NzE5NzNiZDhhMC5wbmc?x-oss-process=image/format,png#align=left&display=inline&height=608&margin=[object Object]&name=image.png&originHeight=608&originWidth=830&size=145069&status=done&style=none&width=830)
    按下图修改
    ![image.png](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9jZG4ubmxhcmsuY29tL3l1cXVlLzAvMjAyMC9wbmcvMTY5NzEyNy8xNTk0MzY3NjEzOTg1LWQ4OTMyMzY5LWQ3NmEtNGRmZC05Yzc2LTdlYzNkODIwNjg1Zi5wbmc?x-oss-process=image/format,png#align=left&display=inline&height=619&margin=[object Object]&name=image.png&originHeight=619&originWidth=855&size=92384&status=done&style=none&width=855)

    配置安装位置

    点击INSTALLATION DESTINATION
    ![image.png](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9jZG4ubmxhcmsuY29tL3l1cXVlLzAvMjAyMC9wbmcvMTY5NzEyNy8xNTk0MzY3NjQ2NDc1LWE4ODI2Zjg3LWY2ZDItNDYxZC1hODhjLWVmYjVjMzNmY2MxMi5wbmc?x-oss-process=image/format,png#align=left&display=inline&height=610&margin=[object Object]&name=image.png&originHeight=610&originWidth=825&size=145273&status=done&style=none&width=825)
    选中硬盘 然后点击Done
    ![image.png](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9jZG4ubmxhcmsuY29tL3l1cXVlLzAvMjAyMC9wbmcvMTY5NzEyNy8xNTk0MzY3NzE5MDA0LTJlOTE1Yjg2LTE4NDMtNDkzZS04NzE2LWIyMGI5NzkyNDc2NS5wbmc?x-oss-process=image/format,png#align=left&display=inline&height=638&margin=[object Object]&name=image.png&originHeight=638&originWidth=856&size=117034&status=done&style=none&width=856)

    开始安装

    点击Begin Installation
    ![image.png](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9jZG4ubmxhcmsuY29tL3l1cXVlLzAvMjAyMC9wbmcvMTY5NzEyNy8xNTk0MzY3NzcxMTg1LTc4OTVmZmQyLTE4NDktNGQwZS04M2M2LWY1NTA2YjQzYzdmZi5wbmc?x-oss-process=image/format,png#align=left&display=inline&height=605&margin=[object Object]&name=image.png&originHeight=605&originWidth=830&size=139739&status=done&style=none&width=830)

    配置root账号的密码

    点击 ROOT PASSWORD
    ![image.png](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9jZG4ubmxhcmsuY29tL3l1cXVlLzAvMjAyMC9wbmcvMTY5NzEyNy8xNTk0MzY3ODEyNTQzLWIzYzMzYzY4LTVkZjItNGJjNi1iMzBmLTM5NTNjMDI4NTJlMi5wbmc?x-oss-process=image/format,png#align=left&display=inline&height=590&margin=[object Object]&name=image.png&originHeight=590&originWidth=802&size=157101&status=done&style=none&width=802)
    输入root密码 两次一致 点击Done 一次不行就两次(实际上是密码太短 点击两次确认使用弱密码)
    ![image.png](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9jZG4ubmxhcmsuY29tL3l1cXVlLzAvMjAyMC9wbmcvMTY5NzEyNy8xNTk0MzY3ODUxMjI4LTRmYTAxZjYzLTlhZjEtNDU4Mi1iMGM4LTg5NGFjY2FkY2Y2OC5wbmc?x-oss-process=image/format,png#align=left&display=inline&height=642&margin=[object Object]&name=image.png&originHeight=642&originWidth=858&size=65433&status=done&style=none&width=858)
    等待一段时间 点击reboot
    ![image.png](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9jZG4ubmxhcmsuY29tL3l1cXVlLzAvMjAyMC9wbmcvMTY5NzEyNy8xNTk0MzY4MDQ0MzMxLTg4MWRlYWYzLTc3MTMtNDM5YS1iYTM1LWZjYzdlNzgwMjk5Mi5wbmc?x-oss-process=image/format,png#align=left&display=inline&height=581&margin=[object Object]&name=image.png&originHeight=581&originWidth=824&size=92145&status=done&style=none&width=824)

    重启完成后登录

    用户名:root
    密码:你设置的密码

    ![image.png](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9jZG4ubmxhcmsuY29tL3l1cXVlLzAvMjAyMC9wbmcvMTY5NzEyNy8xNTk0MzY4MTU3MzA0LTUzZDhkNTA1LWU5MzEtNGFkMi04OTY3LWNmYTI1OTNiNTgwNi5wbmc?x-oss-process=image/format,png#align=left&display=inline&height=196&margin=[object Object]&name=image.png&originHeight=196&originWidth=317&size=3329&status=done&style=none&width=317)

    验证安装

    登录完成后 使用 ip addr 查看你的IP地址

    ![image.png](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9jZG4ubmxhcmsuY29tL3l1cXVlLzAvMjAyMC9wbmcvMTY5NzEyNy8xNTk0MzY4MTQ1NzY3LThkYmY0NTZjLWY2MDMtNDNkNi05YTRkLTk3ZTZjODE0MDg0ZS5wbmc?x-oss-process=image/format,png#align=left&display=inline&height=190&margin=[object Object]&name=image.png&originHeight=190&originWidth=705&size=14589&status=done&style=none&width=705)
    至此 centos的基本安装完毕

    配置Linux

    XShell登录

    使用上节记录查看到的ip地址用XShell登录

    ![image.png](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9jZG4ubmxhcmsuY29tL3l1cXVlLzAvMjAyMC9wbmcvMTY5NzEyNy8xNTk0MzY4MjkzNDY5LTI5ZGJjN2VmLWFjZDQtNDE4MS05NjQ5LTZhZjgyZGI4MjZmNS5wbmc?x-oss-process=image/format,png#align=left&display=inline&height=124&margin=[object Object]&name=image.png&originHeight=124&originWidth=477&size=11087&status=done&style=none&width=477)

    更新

    首先先更新一下centos的依赖

    yum update -y
    

    安装vim

    这个centos是最小安装的镜像 默认没有安装vim文本编辑
    等待上面更新的命令执行完毕后 执行以下命令

    yum install vim -y
    

    关闭防火墙

    因为是开发环境的配置 为了方便我们开发 所以先关闭掉centos的防火墙

    systemctl stop firewalld  
    systemctl disable firewalld 
    

    附: centos防火墙基本使用

    启动: systemctl start firewalld  
    关闭: systemctl stop firewalld  
    查看状态: systemctl status firewalld   
    开机禁用: systemctl disable firewalld  
    开机启用: systemctl enable firewalld
    

    至此 centos的基本配置完毕

    Docker安装

    Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的 Linux或Windows 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。
    docker是现在非常火热的容器化平台

    基于centos7.7安装docker

    卸载旧版本

    sudo yum remove docker \
                      docker-client \
                      docker-client-latest \
                      docker-common \
                      docker-latest \
                      docker-latest-logrotate \
                      docker-logrotate \
                      docker-selinux \
                      docker-engine-selinux \
                      docker-engine
    

    使用yum 安装依赖

    sudo yum install -y yum-utils \
               device-mapper-persistent-data \
               lvm2
    

    添加依赖

    sudo yum-config-manager \
        --add-repo \
        https://mirrors.ustc.edu.cn/docker-ce/linux/centos/docker-ce.repo
    

    安装docker ce

    sudo yum makecache fast
    sudo yum install docker-ce -y
    

    启动docker

    sudo systemctl enable docker
    sudo systemctl start docker
    

    测试 Docker 是否安装正确

    docker run hello-world
    

    ### 配置docker的镜像加速 ```shell sudo mkdir -p /etc/docker sudo tee /etc/docker/daemon.json <<-'EOF' { "registry-mirrors": ["https://uz6p4blc.mirror.aliyuncs.com"] } EOF sudo systemctl daemon-reload sudo systemctl restart docker ``` ### 验证docker镜像加速 > 使用docker info命令
    [root@centos ~]# docker info
    Client:
     Debug Mode: false
    
    Server:
     Containers: 7
      Running: 6
      Paused: 0
      Stopped: 1
     Images: 7
     Server Version: 19.03.12
     Storage Driver: overlay2
      Backing Filesystem: xfs
      Supports d_type: true
      Native Overlay Diff: true
     Logging Driver: json-file
     Cgroup Driver: cgroupfs
     Plugins:
      Volume: local
      Network: bridge host ipvlan macvlan null overlay
      Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
     Swarm: inactive
     Runtimes: runc
     Default Runtime: runc
     Init Binary: docker-init
     containerd version: 7ad184331fa3e55e52b890ea95e65ba581ae3429
     runc version: dc9208a3303feef5b3839f4323d9beb36df0a9dd
     init version: fec3683
     Security Options:
      seccomp
       Profile: default
     Kernel Version: 3.10.0-862.el7.x86_64
     Operating System: CentOS Linux 7 (Core)
     OSType: linux
     Architecture: x86_64
     CPUs: 4
     Total Memory: 7.545GiB
     Name: centos
     ID: 3QOG:3RWM:H72U:QIRL:NBYC:4ZHN:AAUA:AWZI:PWSE:3VTY:TPL3:KZTY
     Docker Root Dir: /var/lib/docker
     Debug Mode: false
     Registry: https://index.docker.io/v1/
     Labels:
     Experimental: false
     Insecure Registries:
      127.0.0.0/8
     Registry Mirrors:
      https://uz6p4blc.mirror.aliyuncs.com/
     Live Restore Enabled: false
    
    [root@centos ~]# 
    
    

    看到Registry Mirrors是你刚刚配置的即为配置成功

    docker-compose安装

    docker-compose是docker三剑客的其中一个 docker-compose可以大量简化我们得Linux命令 只用一个yml文件就可以实现对docker容器得编排
    可以说非常方便了 而且以后的k8s里也运用到了大量的yml 这里可以提前熟悉一下这些语法

    Docker Compose是 docker 提供的一个命令行工具,用来定义和运行由多个容器组成的应用。使用 compose,我们可以通过 YAML 文件声明式的定义应用程序的各个服务,并由单个命令完成应用的创建和启动

    curl -L https://get.daocloud.io/docker/compose/releases/download/1.25.4/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
    sudo chmod +x /usr/local/bin/docker-compose
    

    验证docker-compose是否安装正确

    [root@centos ~]# docker-compose -v
    docker-compose version 1.25.4, build 8d51620a
    

    开发环境配置

    完成docker的以及docker-compose的安装以后 开始陆续进行一些基础中间件的安装
    在下面都使用docker-compose进行安装

    安装MySQL

    mysql可以说是最常用的关系型数据库之一了

    # 在/root/新建一个mysql文件夹
    mkdir msqyl
    cd mysql
    # 新建一个mysql.yml的文件
    vim mysql.yml
    # 按键盘上的i进入插入模式
    

    粘贴下面的任意一个yml配置文件到mysql.yml然后按esc 输入 :wq
    MySQL 5.7

    version: '3.1'
    services:
      mysql:
        restart: always
        image: mysql:5.7.22
        container_name: mysql
        ports:
          - 3306:3306
        environment:
          TZ: Asia/Shanghai
          MYSQL_ROOT_PASSWORD: 123456
        command:
          --character-set-server=utf8mb4
          --collation-server=utf8mb4_general_ci
          --explicit_defaults_for_timestamp=true
          --lower_case_table_names=1
          --max_allowed_packet=128M
          --sql-mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION,NO_ZERO_DATE,NO_ZERO_IN_DATE,ERROR_FOR_DIVISION_BY_ZERO"
        volumes:
          - mysql-data:/var/lib/mysql
    
    volumes:
      mysql-data:
    

    MySQL 8.x

    version: '3.1'
    services:
      db:
        image: mysql
        restart: always
        environment:
          MYSQL_ROOT_PASSWORD: 123456
        command:
          --default-authentication-plugin=mysql_native_password
          --character-set-server=utf8mb4
          --collation-server=utf8mb4_general_ci
          --explicit_defaults_for_timestamp=true
          --lower_case_table_names=1
        ports:
          - 3306:3306
        volumes:
          - ./data:/var/lib/mysql
    

    完成后执行

    docker-compose -f mysql.yml up -d
    

    等待启动

    验证msyql的运行

    输入docker ps
    [root@centos mysql]# docker ps
    CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                               NAMES
    31b2d245e8e3        adminer             "entrypoint.sh docke…"   16 seconds ago      Up 15 seconds       0.0.0.0:8080->8080/tcp              mysql_adminer_1
    f82b2c585931        mysql               "docker-entrypoint.s…"   16 seconds ago      Up 15 seconds       0.0.0.0:3306->3306/tcp, 33060/tcp   mysql_db_1
    
    

    使用Navicat Premium 12链接msyql
    输入连接名 你的主机地址
    用户名:root
    密码: 123456
    显示链接成功即可

    ![image.png](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9jZG4ubmxhcmsuY29tL3l1cXVlLzAvMjAyMC9wbmcvMTY5NzEyNy8xNTk0MzcxNTcxODY3LTM5MTNiYjcwLTBjMjItNGQ3Ny1iY2ZlLWEwYWVkNmE4ODk5ZS5wbmc?x-oss-process=image/format,png#align=left&display=inline&height=658&margin=[object Object]&name=image.png&originHeight=658&originWidth=551&size=46183&status=done&style=none&width=551)

    安装redis

    Redis(Remote Dictionary Server ),即远程字典服务,是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。从2010年3月15日起,Redis的开发工作由VMware主持。从2013年5月开始,Redis的开发由Pivotal赞助
    redis是目前最火热的非关系行数据库 key-value类型的数据库

    # 在/root/新建一个redis文件夹
    mkdir redis
    cd redis
    # 新建一个redis.yml的文件
    vim redis.yml
    # 按键盘上的i进入插入模式
    

    粘贴下面的yml配置文件到redis.yml然后按esc 输入 :wq

    version: '3.1'
    services:
      master:
        image: redis
        container_name: redis-master
        ports:
          - 6379:6379
    

    完成后执行

    docker-compose -f redis.yml up -d
    

    等待启动

    验证redis的运行

    输入docker ps
    [root@centos redis]# docker ps
    CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                               NAMES
    5eeb447fc8dc        redis               "docker-entrypoint.s…"   35 seconds ago      Up 34 seconds       0.0.0.0:6379->6379/tcp              redis-master
    31b2d245e8e3        adminer             "entrypoint.sh docke…"   6 minutes ago       Up 6 minutes        0.0.0.0:8080->8080/tcp              mysql_adminer_1
    f82b2c585931        mysql               "docker-entrypoint.s…"   6 minutes ago       Up 6 minutes        0.0.0.0:3306->3306/tcp, 33060/tcp   mysql_db_1
    
    

    使用RedisDesktopManager链接redis

    点击链接到redis
    输入名字 地址后
    点击测试链接 显示链接redis服务器成功即可

    ![image.png](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9jZG4ubmxhcmsuY29tL3l1cXVlLzAvMjAyMC9wbmcvMTY5NzEyNy8xNTk0MzcxNzE2NTQ4LTYwNDAwZWY4LTMzNDItNGYxMi04NTI1LTMzZTExZDM3NjU1ZC5wbmc?x-oss-process=image/format,png#align=left&display=inline&height=862&margin=[object Object]&name=image.png&originHeight=862&originWidth=600&size=94734&status=done&style=none&width=600)

    安装rabbitmq

    RabbitMQ是实现了高级消息队列协议(AMQP)的开源消息代理软件(亦称面向消息的中间件)。RabbitMQ服务器是用Erlang语言编写的,而集群和故障转移是构建在开放电信平台框架上的。所有主要的编程语言均有与代理接口通讯的客户端库。
    rabbitmq是目前我经常使用的一块消息队列中间件

    # 在/root/新建一个rabbitmq文件夹
    mkdir rabbitmq
    cd rabbitmq
    # 新建一个rabbitmq.yml的文件
    vim rabbitmq.yml
    # 按键盘上的i进入插入模式
    

    粘贴下面的yml配置文件到redis.yml然后按esc 输入 :wq

    version: '3.1'
    services:
      rabbitmq:
        restart: always
        image: rabbitmq:management
        container_name: rabbitmq
        ports:
          - 5672:5672
          - 15672:15672
        environment:
          TZ: Asia/Shanghai
          RABBITMQ_DEFAULT_USER: rabbit
          RABBITMQ_DEFAULT_PASS: 123456
        volumes:
          - ./data:/var/lib/rabbitmq
    

    完成后执行

    docker-compose -f rabbitmq.yml up -d
    

    等待启动

    验证rabbitmq的运行

    [root@centos rabbitmq]# docker ps
    CONTAINER ID        IMAGE                 COMMAND                  CREATED             STATUS              PORTS                                                                                        NAMES
    f422789ff3f1        rabbitmq:management   "docker-entrypoint.s…"   5 minutes ago       Up 5 minutes        4369/tcp, 5671/tcp, 0.0.0.0:5672->5672/tcp, 15671/tcp, 25672/tcp, 0.0.0.0:15672->15672/tcp   rabbitmq
    5eeb447fc8dc        redis                 "docker-entrypoint.s…"   31 minutes ago      Up 31 minutes       0.0.0.0:6379->6379/tcp                                                                       redis-master
    31b2d245e8e3        adminer               "entrypoint.sh docke…"   36 minutes ago      Up 36 minutes       0.0.0.0:8080->8080/tcp                                                                       mysql_adminer_1
    f82b2c585931        mysql                 "docker-entrypoint.s…"   36 minutes ago      Up 36 minutes       0.0.0.0:3306->3306/tcp, 33060/tcp                                                            mysql_db_1
    
    

    浏览器上输入ip:15672

    用户名: rabbit
    密码: 123456

    ![image.png](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9jZG4ubmxhcmsuY29tL3l1cXVlLzAvMjAyMC9wbmcvMTY5NzEyNy8xNTk0MzczNTA0NTcyLTkxMmVjMGMxLWFmNDktNDg2ZC04YzUwLTgwNDk5ZmU1MGY2Zi5wbmc?x-oss-process=image/format,png#align=left&display=inline&height=200&margin=[object Object]&name=image.png&originHeight=200&originWidth=306&size=8738&status=done&style=none&width=306)
    ![image.png](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9jZG4ubmxhcmsuY29tL3l1cXVlLzAvMjAyMC9wbmcvMTY5NzEyNy8xNTk0MzczNTE4NTAyLWFjNTIzYWRjLTc5NDMtNDdkOC05ZWYxLTA5YzQzMmJhMmIxYS5wbmc?x-oss-process=image/format,png#align=left&display=inline&height=415&margin=[object Object]&name=image.png&originHeight=415&originWidth=559&size=28523&status=done&style=none&width=559)

    安装elk日志收集

    ELK是Elasticsearch、Logstash、Kibana三大开源框架首字母大写简称。市面上也被成为Elastic Stack。其中Elasticsearch是一个基于Lucene、分布式、通过Restful方式进行交互的近实时搜索平台框架。像类似百度、谷歌这种大数据全文搜索引擎的场景都可以使用Elasticsearch作为底层支持框架,可见Elasticsearch提供的搜索能力确实强大,市面上很多时候我们简称Elasticsearch为es。Logstash是ELK的中央数据流引擎,用于从不同目标(文件/数据存储/MQ)收集的不同格式数据,经过过滤后支持输出到不同目的地(文件/MQ/redis/elasticsearch/kafka等)。Kibana可以将elasticsearch的数据通过友好的页面展示出来,提供实时分析的功能。


    # 在/root/新建一个elk文件夹
    mkdir elk
    cd elk
    # 新建一个elk.yml的文件
    vim elk.yml
    # 按键盘上的i进入插入模式
    

    复制如下内容到elk.yml

    elk.yml

    version: "3"
    services: 
      elasticsearch:
        image: registry.cn-hangzhou.aliyuncs.com/yalong_lee_release/elasticsearch:v7.4.1
        ports:
          - "9200:9200" 
          - "9300:9300"
        restart: "always" 
        container_name: elasticsearch 
        hostname: elasticsearch
        environment:
          - "discovery.type=single-node"
          - "cluster.name=EsForLog" 
          - "ES_JAVA_OPTS=-Xms512m -Xmx512m" 
        volumes:
          - ./data:/usr/share/elasticsearch/data
      kibana: 
        image: registry.cn-hangzhou.aliyuncs.com/htsec/kibana:7.4.1 
        restart: "always" 
        container_name: kibana 
        hostname: kibana
        volumes:  
          - ./kibana.yml:/usr/share/kibana/config/kibana.yml
        links:
          - elasticsearch:es01  
        depends_on:
          - elasticsearch 
        ports:
          - "5601:5601" 
      logstash: 
        image: registry.cn-hangzhou.aliyuncs.com/logss/logstash:7.4.1  
        restart: "always" 
        container_name: logstash 
        hostname: logstash
        volumes:
          - ./logstash.conf:/usr/share/logstash/pipeline/logstash.conf 
        links:
          - elasticsearch:es01 
        depends_on:
          - elasticsearch
        ports:
          - "5044:5044"  
    
    

    在elk目录下创建一个data 并且给与权限

    mkdir data
    chmod 777 data
    

    在elk下创建kibana配置文件

    vim kibana.yml
    

    复制如下内容到kibana.yml
    kibana.yml

    elasticsearch.hosts: http://es01:9200
    server.host: "0.0.0.0"
    server.name: kibana
    xpack.monitoring.ui.container.elasticsearch.enabled: true
    i18n.locale: zh-CN
    

    在elk下创建logstash配置文件

    vim logstash.conf
    

    复制如下内容到logstash.conf
    logstash.conf

    input {
    	tcp {
    		mode => "server"
    		host => "0.0.0.0"
            port => 5044
            codec => json_lines
        }
    }
    output {
    	elasticsearch {
    		hosts => ["http://es01:9200"]
    		index => "%{[appname]}-%{+YYYY.MM.dd}"
    	}
    	stdout {
    		codec => rubydebug
    	}
    }
    

    完善上述操作后执行

    docker-compose -f elk.yml up -d
    

    等待elk的运行

    [root@centos elk]# docker ps
    CONTAINER ID        IMAGE                                                                       COMMAND                  CREATED             STATUS              PORTS                                                                                        NAMES
    eb6edbb49907        registry.cn-hangzhou.aliyuncs.com/htsec/kibana:7.4.1                        "/usr/local/bin/dumb…"   21 minutes ago      Up 14 minutes       0.0.0.0:5601->5601/tcp                                                                       kibana
    c99c65029eb8        registry.cn-hangzhou.aliyuncs.com/logss/logstash:7.4.1                      "/usr/local/bin/dock…"   21 minutes ago      Up 14 minutes       0.0.0.0:5044->5044/tcp, 9600/tcp                                                             logstash
    346cfcaf5f89        registry.cn-hangzhou.aliyuncs.com/yalong_lee_release/elasticsearch:v7.4.1   "/usr/local/bin/dock…"   21 minutes ago      Up 14 minutes       0.0.0.0:9200->9200/tcp, 0.0.0.0:9300->9300/tcp                                               elasticsearch
    f422789ff3f1        rabbitmq:management                                                         "docker-entrypoint.s…"   50 minutes ago      Up 50 minutes       4369/tcp, 5671/tcp, 0.0.0.0:5672->5672/tcp, 15671/tcp, 25672/tcp, 0.0.0.0:15672->15672/tcp   rabbitmq
    5eeb447fc8dc        redis                                                                       "docker-entrypoint.s…"   About an hour ago   Up About an hour    0.0.0.0:6379->6379/tcp                                                                       redis-master
    31b2d245e8e3        adminer                                                                     "entrypoint.sh docke…"   About an hour ago   Up About an hour    0.0.0.0:8080->8080/tcp                                                                       mysql_adminer_1
    f82b2c585931        mysql                                                                       "docker-entrypoint.s…"   About an hour ago   Up About an hour    0.0.0.0:3306->3306/tcp, 33060/tcp                                                            mysql_db_1
    
    

    验证elk的运行

    在浏览器输入ip:5601进入kibana的后台页面
    ![image.png](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9jZG4ubmxhcmsuY29tL3l1cXVlLzAvMjAyMC9wbmcvMTY5NzEyNy8xNTk0Mzc2MTYwNzA5LTM2NmY2OTg1LTgyMjYtNDk5Ny1iYTg0LWNkZDZkZTA2NzY5Ni5wbmc?x-oss-process=image/format,png#align=left&display=inline&height=499&margin=[object Object]&name=image.png&originHeight=499&originWidth=1600&size=77837&status=done&style=none&width=1600)

    附录: docker常用命令

    ### 查看运行容器
    docker ps
    
    ### 查看所有容器
    docker ps -a
    
    ## 进入容器
    ### 其中字符串为容器ID:
    docker exec -it d27bd3008ad9 /bin/bash
    
    ### 停用全部运行中的容器:
    docker stop $(docker ps -q)
    
    ### 删除全部容器:
    docker rm $(docker ps -aq)
    
    ### 一条命令实现停用并删除容器:
    docker stop $(docker ps -q) & docker rm $(docker ps -aq)
    
    ### docker所有命令查看:
    docker help
    
    
    展开全文
  • 微服务的劣势 必须要开发服务间通信机制 需要经常处理“部分失败”的情况,因为一个请求现在是是一组服务的调用。 数据库结构设计和操作,例如跨表操作,数据一致性(事务)问题等。 测试更加困难,因为要测试你的...

    英文原文出自:https://www.nginx.com/blog/introduction-to-microservices/

    笔记首发于我的语雀,有空来帮我点个稻谷呀。

    PS: 知乎对markdown支持真是各大平台里最蔡的orz

    1 简介

    monolithic app(都写在一起)的劣势

    08a50e00ba6f4e08b6f9f99fbf373764.png
    • 代码依赖极其复杂
    • 难以理解
    • 启动时间变长
    • CPU密集型逻辑和内存消耗型逻辑无法拆开优化,浪费云计算资源
    • 可靠性变差:一处内存泄漏,全家升天
    • 难以做架构升级,例如更换语言或框架

    微服务

    ba36ed1338df5b5ae3b723d5fe5dfcf2.png
    • 把你的巨型应用拆解成小型的独立的互联的服务们
    • 服务之间互相之间提供服务和消费服务
    • 客户端通过API网关来调用服务们
    • 运行时的一组服务可以是多台物理机上的多个container
    • 服务拥有自己的独立的数据库存储,这意味着服务可以选择自己最适合的数据库类型。

    微服务的优势

    • 拆解了复杂的应用,单个服务更好迭代和维护。
    • 每个服务可以自由地选择最合适的技术栈。
    • 服务可以分开部署,可以更加自由地进行持续集成。

    微服务的劣势

    • 必须要开发服务间通信机制
    • 需要经常处理“部分失败”的情况,因为一个请求现在是是一组服务的调用。
    • 数据库结构设计和操作,例如跨表操作,数据一致性(事务)问题等。
    • 测试更加困难,因为要测试你的服务,你必须先启动其他服务。
    • 在维护或更新时,你通常需要更新多个服务。
    • 服务数量众多时,部署也是一个难题。

    2 构建微服务:使用API网关

    • 【背景】例如在做一个电商宝贝详情时,你客户端需要调:购物车服务、订单服务、类目服务、评价服务、库存服务、发货服务、推荐服务....

    不使用API网关,挨个调过去

    • 客户端通过移动网络发送N个网络请求,是非常不靠谱的
    • 服务可能用的并非是web友好的协议,例如thrift,无法提供服务。
    • 让重构微服务们变得困难,因为它们被客户端直接依赖了

    使用API网关

    • API网关可以调用多个微服务, 然后提供一个“item/detail?id=xxxx”的统一接口
    • API可以顺便做负载均衡、监控、授权和认证等等多种统一功能
    • 【优】封装了应用的内部结构设计,客户端只需要和API网关通信
    • 【优】可以通过服务,自由组合出最适合客户端的API
    • 【劣】你需要单独开发、部署、管理API网关
    • 【劣】API网关可能成为开发的瓶颈,例如开发者暴露新的服务时要更新到API网关

    实现API网关

    • 为了API网关的性能和可扩展性,应该支持异步NIO。
    • 在JVM上你可以使用Netty、Vertx、Spring Reactor等NIO框架
    • 在非JVM上你可以使用node.js来实现NIO
    • 你还可以使用Nginx Plus(要钱的)

    使用Reactive Programming

    • 对于互不相关的服务,应该同时一起调用。有先后顺序的服务可能要定义好前置和后置。
    • 使用传统的异步+回调的方式来书写组合服务的代码会让你很快陷入回调地狱。
    • Java、Scala、JS中都有响应式的方案,你还可以使用ReactiveX来书写这类代码。

    服务调用:

    通常有两种调用方式

    • 异步——消息队列
    • 同步——HTTP或者Thrift等

    服务发现

    • 过去你通常手动控制服务的ip地址,但是在微服务体系中,你无法做到。
    • 由于各个服务的随时扩容和升级,它们的地址都是在动态变化的。
    • 所以API网关需要有服务注册,服务发现的能力。不论是server-side发现,还是client-side发现。

    处理部分失败

    • API网关不可以因为下游的失败而block住,它要根据场景来决定如何处理错误。
      • 例如只是商品推荐服务挂了,商品详情页接口应该仍然返回其他所有数据
      • 如果是商品基础信息挂了,商品详情页接口应该反馈错误给到客户端。
    • 可以返回硬编码打底数据,或者缓存数据。(API网关做, 服务无感知)
    • 安利了一下Netflix Hystrix, 但是似乎已经处于维护状态不再更新了。

    3 构建微服务:微服务架构中的跨进程通信

    • 【背景】在monolithic应用中,组件之间互相通过语言级别的方法就可以进行调用,但是在微服务应用中,这些组件都被分布式地部署在不同的机器上的不同容器里。基本每个服务都是一个进程,所以服务们不得不使用跨进程通信(IPC)机制。

    交互方式

    • 一对一通信 vs 一对多通信
    • 同步 vs 异步

    65186e289254dbc967f43687ea2e888a.png
    • request/response: client发起请求然后同步等待响应结果。
    • notifications:client发出一个请求,但并不需要返回,也不等待。
    • request/async response: client发出一个请求,但响应是异步的,在等待响应的过程中,client并不阻塞。
    • publish/subscribe: client发出一条消息,被一个或多个感兴趣的服务消费。
    • public/async responses: client发出一个请求消息,然后等待一段时间来接收感兴趣的服务的返回。
    • 每个服务都可能用上述多种交互方式,例如下图

    6556a46d7da7696f976d78721281fece.png

    定义API

    • 服务的API是一种服务和它的客户端们之间的约定。
    • 使用某种接口定义语言(IDL)非常重要,例如Protobuf。
    • 你甚至可以使用API-first这种方式,也就是先定义API再实现它,来进行开发。
    • API定义依赖于你使用的IPC机制,例如使用消息那么API就需要消息通道和消息类型。

    更新API

    • 在monolithic的app里,你一般改了API后,去代码里直接改所有的调用处.
    • 在微服务体系里, 更新API会困难得多,你没办法让你服务的消费者挨个更新。你可能要增量地添加新版本的服务,线上可能同时存在两个版本的API,这是一种非常重要的更新策略。
    • 为了实现上述能力,一种可行的方式是添加版本号,让多个版本的API同时存在。

    处理部分失败

    • 在微服务体系中,部分失败是非常常见的,因为所有服务们都在不同的进程里。
    • 假设有一个场景,你的产品详情页里需要使用推荐服务,而此时推荐服务挂掉了:

    cc20dae13b7956b44e66245dc3b3438a.png

    如果你按照一直等待去设计,那么很有可能会消耗掉你所有的线程,导致产品详情服务彻底挂掉

    • 下面有4条由Netflix推荐的部分失败错误处理策略。
      • 网络超时:永远不要一直等待,一定要有超时重试/超时失败机制。
      • 限制等待中请求数量:等待中的请求应该有一个上限值,一旦上限达到了,就不应该再处理请求,这些超出限额的请求应该立即失败。
      • 短路模式:当失败率达到一定程度时,后续的请求应该立即失败,不再请求。短路后,应该每隔一段时间重试,如果重试成功,那么就不再短路。
      • 提供降级:提供失败时的降级逻辑,例如获得缓存数据。

    IPC机制

    • 异步、基于消息的IPC机制
      • client向某服务发送一条消息,但并不等待它。如果这次调用需要返回,被调用服务会也异步通过消息返回给client。client完全基于异步,也就是不等待的方式来编写。
      • 消息一般由header和body构成,并且通过channel来交换。
      • 两种消息channel:1. 点对点 2. pub/sub
      • 案例:

    f8870c82c384472428c105651ada1c58.png
      • 出行服务发一条消息“一个新出行创建了!”到名叫“新的出行”的pub/sub型channel中,通知所有感兴趣的服务(比如派单服务)。派单服务找到了合适的司机以后,发送一条消息“司机接单了!”到一个名叫“派单”的pub/sub型channel中,通知所有感兴趣的服务。
      • 消息队列实现有非常多种:RabbitMQ、Kafka、ActiveMQ.....
      • 用消息机制的优点:
        • 把服务的consumer和provider通过消息解耦了。
        • 消息可堆积,比起实时调用有更高的容错率。
        • 调用方式也解耦了,consumer和provider之间只需要遵守消息约定即可。
      • 用消息机制的缺点:
        • 更高的运维复杂性,消息系统也是一个要维护的系统啊!
        • 要实现请求-响应这种同步请求会更加麻烦
        • 【作者补充】消息队列的高可用、不被重复消费、可靠性、顺序性都是非常复杂的课题。
    • 同步、请求/响应型的IPC
      • 通常来说,一个线程会在等待请求时阻塞。有些可能已经通过Future或者Rx Observables这种Ractive Pattern的东西把它变成了异步的方式。
      • 但是在这种类型的IPC里,client通常希望请求能够尽快及时地返回。
      • 常见的主要由两种协议:Rest、Thrift
      • 基于HTTP方式的协议(Rest)的好处:
        • 简单熟悉
        • HTTPAPI可以直接在浏览器、Postman、curl等多种环境下测试。
        • 直接支持 请求/响应 模式
        • 没有任何中间代理,系统架构简单
      • 基于HTTP方式的协议(Rest)的坏处:
        • 只支持 请求/响应 模式
        • provider和consumer都必须活着不能挂
      • 基于HTTP方式的一些IDL或平台:RAML、Swagger
      • Thrift
        • 使用一个C风格的IDL来定义API,并且使用Thrift编译器来生成客户端和服务端代码模板。
        • 支持C++、Java、Pyhton、Ruby、Erlang、Node.js
        • Thrift方法可以返回空值,也就是可以实现单向的通知,并不一定要返回。
        • 支持JSON/二进制等格式
    • 消息格式
      • 不管用什么方式和语言,最好选择语言无关的消息格式,你无法保证将来你不换语言。
      • 在文本和二进制中,tradeoff大概就是包大小or人类可阅读性。

    4 微服务架构中的服务发现

    为什么使用服务发现?

    • 你以前,你可能把要调用的IP放在配置里,然后直接调用
    • 但是在云时代的微服务应用中,你应该不太能这么做,看图:

    14ea206b54d931803d93a48f7ecc29f5.png
    • 你会发现,服务实例们都有着动态分配的网络位置,而且这些位置由于扩容、更新等等还在变化。
    • 目前主要由两种服务发现:client侧服务发现、server侧服务发现

    client侧服务发现

    93e16b7822adbc5f3436c09a0b122a16.png
    • 这种模式下,consumer决定了所调用服务的网络地址。所有的服务provider,都把自己的网络地址,注册到服务注册中心,consumer拿到了一坨ip地址之后,自己选择一个load-balancing策略,然后调用其中一个。
    • 服务Provider在启动时向注册中心注册服务,在结束进程时给注册中心注销服务。服务的健康通过心跳机制来进行保障。
    • Netflix OSS是一个client侧服务发现的好例子,Netflix Eureka是一个REST型服务注册中心。
    • Netflix Ribbon是一个IPC客户端,能够和Eureka合作,提供load-balancing。
    • 优点:1. 简单直接 2. 由于consumer决定了路由,可以做灵活的、应用特定的负载均衡策略
    • 缺点:耦合了consumer和服务注册中心,你必须给每个编程语言实现consumer侧的服务发现逻辑。

    server侧服务发现

    9a38cb9c9c06e1c9a908cb8d1dd87965.png
    • consumer通过一个load balancer来请求provider,load balancer要请求服务注册中心来获得所有可提供服务的实例以及它们的网络地址。也就是load-balancer决定了到底要请求谁。
    • 亚马逊的ELB就是一个server侧服务发现路由。ELB把服务注册直接做到了自己里面。
    • Nginx也可以充当server侧服务发现中的load balancer,比如这篇文章里,你可以使用Consul Template来动态更新nginx的反向代理。
    • 一些部署环境例如K8S或者Marathon,在集群里的每个宿主上都运行Proxy,这个Proxy就扮演了server侧服务发现中的load-balancer。如果你想给一个服务发请求,一个consumer必须通过proxy来调用。
    • 优点:
      • consumer和服务发现是完全解耦的,无脑请求load-balancer就好了。
      • 不用再给每个语言实现一套load-balancing机制了。
      • 有些部署环境甚至直接提供了这种load-balancing服务。
    • 缺点:如果没有提供好的load-balancing服务,你就要自己实现。

    服务注册中心

    • 概念详解
      • 它就是一个服务实例们网络位置的数据库。
      • 它必须高可用,并实时更新。
      • 它其实是一坨实例们,这些实例们要通过某种副本协议来保持一致性
    • 比如Netflix Eureka,它是基于REST的。它通过POST方法来注册服务,每30秒通过PUT方法刷新一次,通过DELETE方法删除服务,通过GET方法来获得一个可用的服务实例。
    • Netflix为了实现服务注册的高可用性,通过运行N个Eureka实例,使用DNS的TEXT记录来存储Eureka集群的配置,这个配置也就是一个可用区->一组网络地址的map。当一个新的Eureka启动,它就请求DNS来获得Eureka集群配置,并且给它自己一个新的IP。Eureka的clients,services就请求DNS来发现Eureka实例们的地址,并且会尽可能选相同可用区的Eureka实例。
    • 其他的服务注册中心们还有
      • etcd:K8S和Cloud Foundry用的它
      • consul
      • Zookeeper:大家最熟悉了
    • 在K8S、Marathon、AWS中并没有显式的、单独的服务注册中心,因为它们是内置的基础设置。

    服务注册的方式

    • 目前主要有两种方式来处理服务的注册和注销:自注册模式和三方注册模式。
    • 自注册模式

    9500904a8a217b048cd0bb064d09b93b.png
      • 这种情况下,服务实例自己负责注册和注销它提供的服务,同时服务自己还需要不停地发送心跳包来阻止自己的注册过期。
      • Netflix OSS Eureka client是一个很好的自注册例子。Spring Cloud中也可以直接使用注解来实现注册方式。
      • 优点:简单直接、不需要其他系统组件。
      • 缺点:把服务实例和注册中心耦合起来了,你要实现各个编程语言的注册代码。
    • 三方注册模式

    591902fab12d32c117772a1777582d02.png
      • 顾名思义,服务实例们要向一个注册管理者(registrar)来进行注册,而注册管理者也通过健康检查机制来跟踪服务实例们的情况,随时注销挂掉的服务实例。
      • 有一个开源的注册管理者叫做Registrator ,它能自动注册和注销以docker container方式部署的服务实例。Registrator支持etcd和Consul。
      • 还有一个有名的注册管理者是NetflixOSS Prana,它主要是为了非JVM语言设计的,它是一个sidecar应用,也就是说它跟着每一个服务实例运行。Prana和Eureka配合,向Eureka进行注册和注销服务。
      • 注册管理者,也是很多部署环境的内置基础设施,例如在AWS EC2和K8S中都是。
      • 优点:服务和服务注册中心解耦、你也不再需要去实现特定语言的注册逻辑。
      • 缺点:如果部署环境没提供注册管理者,那你就要自己实现。

    5 微服务中事件驱动的数据管理

    背景

    • 在一个monolithic的应用中,使用关系型数据库的一个好处是,你可以使用符合ACID原则的事务。
    • ACID原则
      • Atomicity 原子性: 变更要么都成功,要么都失败。
      • Consistency 一致性:数据库的状态永远是一致的。
      • Isolation 独立性:事务之间不会有交错执行的状态(因为可能会导致数据不一致)。
      • Durability 持久性:事务成功后,修改是持久的。
    • 另一个好处是你可以使用SQL,你可以轻松地进行多表操作,数据库帮你解决大部分性能问题。
    • 遗憾的是当切换到微服务架构以后,这些好处你就不再能够享受,因为所有的数据都被各自的微服务所拥有,也就是说他们拥有各自独立的数据库,数据的访问只能通过API层面来进行。
    • 来吧,更糟糕的是:不同的微服务可能还用了不同类型的数据库。例如NoSQL系列的,graph型的(例如Neo4j)。所以微服务架构中通常混用各种类型的数据库,我们称之为polyglot persistence 。

    挑战1:如何在多个微服务中实现事务

    • 假设有一个在线的B2B商店,“客户服务”维护了客户信息,“订单服务”管理订单们,并且保障一个新订单不会用完客户的余额。
    • 在过去的monolithic版的应用中,我们用一个事务,就能搞定“检查余额够不够+创建订单”这件事。
    • 但是在微服务体系中,我们的ORDER表和CUSTOMER表现在是私有的:

    7c1f249ae9bfb46d1a29920f74dc2fea.png
    • 订单服务并无法直接访问CUSTOMER表,它只能通过客户服务提供的API来间接修改CUSTOMER表。也许你可以使用分布式事务,也叫two-phase-commit(2PC)来解决。但是在现代化的应用中,你很难使用2PC。著名的CAP theorem告诉我们,在ACID中你要抉择要C还是A,而一般更好的选择都是A。而且,在很多NoSQL的数据库中根本不支持2PC。

    挑战2:如何进行多表查询

    • 假设你的客户端需要展示客户的信息以及他所有的订单。
    • 如果订单服务提供了根据客户id查它订单的服务,那么你可以直接调这个服务。
    • 但是如果订单服务,没有提供这个服务,比如只支持按照订单id查询时,你该怎么办呢?

    事件驱动架构

    • 在大部分应用中,解决方案就是使用数据驱动架构。当一个值得注意的事情发生了以后,这个微服务发出一个事件,比如“它更新了某个entity”这件事。其他对此感兴趣的微服务订阅这些事件,当它们收到这件事情时,就做它们自己的业务逻辑,比如把自己对于这个entity的冗余字段也更新一下。
    • 你可以使用事件来实现跨越多个服务的事务,这样的一个事务,包括的许多步骤,每个步骤包括一个微服务更新自己的业务逻辑entity,并且发出一个事件通知下一些微服务。来看下面这个流程:
      • 图1:订单服务创建了一个新订单,发出一个“一个订单创建辣!!”的消息

    b88021cd15475692009398317b35a12e.png
    • 图2:客户服务消费这个“一个订单创建辣!!”消息,并且给这个订单预留了余额,然后发送一个“已预留余额”事件

    667cf9c7d87104dbf4ab84577df5ee06.png
    • 图3:订单服务消费“余额已预留”事件,并且把订单状态设为“创建成功”

    6a33196fa7c1044862e21da871ab1f88.png
    - 这里面需要假设
    - 每个服务自动地更新数据库,并且发布事件
    - 消息代理必须保证事件至少都被交付了一次
    • 尽管如此你也只是实现了事务,没有实现ACID的事务,这仅仅是提供了弱保障,例如eventual consistency. 这样的事务模型被称为BASE model.
    • 【解决查询问题】你还可以使用事件来维护一个额外"物料化视图",这个视图包含的预先join好的,来自多个微服务的数据。例如可以专门有一个“客户订单视图”服务,来专门订阅相关事件(客户服务产生的事件、订单服务产生的事件等),然后更新这个视图。

    7e1579d9768b025d7f4023beaedb131b.png
      • 你可以使用文档化数据库例如MongoDB来实现这个额外视图,并且给每一个客户都存一个document。这样当有一个客户来的时候,你可以光速地反馈这个客户的相关订单,因为你已经事先存好了。
    • 事件驱动架构的优点
      • 它使得跨多个服务的普通事务得以实现。
      • 它让应用可以通过“物料化视图”实现快速查询。
    • 事件驱动架构的缺点
      • 编程将更加更加复杂
      • 你必须得实现补偿事务(回滚等)来从应用级错误中恢复。例如:当你检查余额失败时,你应该取消订单。
      • 应用将要面对数据不一致的情况,例如“物料化视图”中的数据并非最新的。而且还要处理事件相关的各种问题,比如重复消费(幂等性),漏消费等问题(其实也就是消息队列常见问题系列)。

    实现原子性

    • 【背景】在事件驱动架构里,你还会遇到一个原子性问题
      • 假设订单服务要插入订单表,同时发出一个“订单创建辣!”事件,这两步操作必须要原子地完成。
      • 假设服务在插入了订单表,发出事件之前挂掉了,那么系统就会出现一致性问题。
      • 通常标准的做法是使用分布式事务,但是如上面所说(比如CAP theorem),这并不是我们想做的。
    • 使用本地事务完成发送事件
      • 这个操作有个术语叫做multi‑step process involving only local transactions
      • 借助本地事务,其实就是你要一个本服务的事件表,它的作用类似消息队列:

    77804304667845fb12687674dd81c269.png
        • 事务1:订单服务插入一个新订单,并且在事件表里插入一个新的订单创建事件。
        • 事务2:事件发送线程读取事件表找到未发送的事件,更新时间并标记事件已发送。
        • 【笔记】这样就保障了“插表+创未发事件”和“事件发送并更新事件状态”的原子性,首先这两个因为是事务所以一定全成功或者全失败,其次是万一在两者之间的时候挂掉了,重启以后事件发送线程还会继续事务性地读取未发事件并重新发送。
      • 优势:不依赖2PC(分布式事务)也能保障每次更新的原子性,发送的也是仍然是业务逻辑层面的事件。
      • 劣势:写代码容易漏写(??我反正没看懂原文啥意思,因为复杂就特么能漏写??)。当使用NoSQL型数据库时会很困难,因为它们的查询能力和事务性都比较差。
    • 挖掘数据库事务日志
      • 另一种不用2PC实现原子性的方法就是,有一个单独的线程去挖掘数据库事务或者commit日志。也就是数据库被更新了以后,就有日志,而这个挖日志线程就读日志,然后发消息给消息代理。

    7b35496c26ad5eb2db22a0668fc05127.png
      • 一种实现方式就是使用开源的LinkedIn Databus ,它可以挖掘Oracle事务日志并发送消息。LinkdeIn用它来保障多个数据存储的一致性。
      • 另一个例子是streams mechanism in AWS DynamoDB,是一种托管的NoSQL数据库,它有一种DynamoDB流,按照时间顺序记录了24小时内的增删改查。应用可以读这些变化来发送事件。
      • 优势:保障了每次更新都可以发送事件。事务日志也可以简化应用逻辑,因为把事件发送和应用业务逻辑拆分开来了。
      • 劣势:每个数据库的事务日志都不太一样,并且随着数据库版本变化,而且你还需要做高层业务逻辑到底层数据库日志的转换。
    • 使用数据溯源
      • 数据溯源是:不直接存储实体现在的状态,它则是存储数据变化的事件(是不是想到了Redux的Action和时间旅行?)。应用会回放所有的数据变化事件来更新实体的状态。相当于先事件再业务了,所以保障了原子性。
      • 举个 ,按照传统的做法,一个ORDER实体对应数据库里ORDER表,但是在数据溯源方式里,表里存的都是状态变化:订单创建、确认、发货、取消等等。

    0e19a11506d9975510807a29162dbf0e.png
      • 事件都存储在了Event Store,这个Event Store其实就像架构里的事件代理。它提供了其他服务订阅这些事件的API。
      • 优势:
        • 顺便就实现了事件代理,一举两得。
        • 它用一种微服务的方式解决了数据一致性问题。
        • 由于是持久化事件而非实体,他基本避免了 object‑relational impedance mismatch problem。
        • 业务逻辑和业务实体耦合程度低,这让它具备更好的迁移性。
      • 劣势:它是一种完全不一样的编程范式,有陡峭的学习曲线。Event Store只直接支持按主键查询业务实体。你必须使用Command Query Responsibility Segregation来实现查询。

    6 选择一种微服务部署策略

    动机

    • 部署monolithic应用时,你通常是在N台物理机(或虚拟机)上部署M个相同的服务实例。这种部署要比微服务要更直接、简单。
    • 微服务通常包括上百的服务,并且它们用了不用的语言和框架。为了让某个功能运行,你可能要起一坨服务才能work。每个服务都有自己单独的部署、资源消耗、扩容、监控的方式。所以微服务的部署虽然很困难,但是也必须要保障快速、可靠、低耗。

    每个宿主机多个服务实例模式

    • 这种模式就是,你在多台机器上部署多个不同的服务实例,不同的服务实例在不同的端口上。

    b6bfc094e0131f2c0a259aa64a2d236f.png
    • 这种模式还有很多变种,例如
      • 每一个服务实例是一个或一组进程
        • 部署一个Java服务实例作为一个web应用放在Apache Tomcat 上面。
        • 一个Node.js服务实例可能包含一个父进程和多个子进程。
      • 在同一个进程或进程组运行多个服务实例
        • 你可以在同一个Tomcat上运行多个java web应用
        • 在OSGI容器上运行多个OSGI的bundle
    • 优势
      • 资源利用相对合理有效,它们共享操作系统和服务器。例如:多web应用共享tomcat和JVM。
      • 部署非常快速,你只要把代码或者构建产物copy到机器上然后启动就行了。
      • 启动服务非常迅速,因为服务进程就是它自己,它就启动自己就好了。
    • 劣势
      • 服务实例之间没有太多隔离,就算你可以监控每个服务用了多少资源,你没办法限制每个服务实例能用多少。有一些服务也许可以消耗掉所有的内存和CPU。如果是同一个进程下的多个服务实例,就更加没有隔离了,他们可能共享比如JVM堆。
      • 运维团队必须知道部署你这个服务的细节,因为不同的应用实现方式都不一样,语言、框架、依赖、环境都可能不太一样。这会增加运维的风险。

    每个宿主机一个服务实例模式

    • 另一种方式就是,每个宿主机只有一个服务实例。这种模式下主要由两种子模式:每个虚拟机一个服务实例和每个容器一个服务实例
    • 每个虚拟机一个服务实例
      • 你把每一个服务都打成一个虚拟机镜像,例如 Amazon EC2 AMI。每个服务实例都是一个运行这个镜像的虚拟机

    6e5e09c66ca947e98b75b25f9a715be7.png
      • Netflix就用这种方式来部署它的视频串流服务,它使用 Aminator来把每个服务打成AWS EC2 AMI,每个服务实例运行在一个EC2身上。
      • 还有很多其他工具你可以用来构建你自己的VM,你可以用一些持续集成工具(比如Jenkins)来调用Animator来打包成虚拟机镜像。Packer.io 也是一个不错的选择,它支持各种虚拟化技术,不仅只有EC2。
      • CloudNative有一个叫Bakery的服务,它是一个用来创建EC2 AMI的SaaS。你可以配置你的CI服务器来调用Bakery(当然前提是你过了你的测试),Bakery会帮你把你的服务打包成成一个AMI。
      • 优势
        • VM之间相互独立,拥有固定的CPU和内存,不会互相攫取资源。
        • 可以借助成熟的云计算基础设施,例如AWS,来快速扩张和部署。
        • 把你的服务封装成了VM以后,就是黑盒了,部署不需要关心细节。
      • 劣势
        • 资源利用更加低效,因为有时候服务并不能榨干虚拟机的性能,而虚拟机就会有性能剩余。
        • 基于上一点,很多云服务按照虚拟机数量收费,并不管你的虚拟机忙还是闲。
        • 当部署新版本的虚拟机时通常很慢,因为虚拟机大小通常都是比较大的,并且初始化,启动操作系统等等也需要时间。
        • 维护虚拟机本身也是一个很重的担子。
    • 每个容器一个服务实例模式
      • 每个服务实例运行在它自己的容器里。容器是一种 virtualization mechanism at the operating system level,你可以简单理解为更轻量级更厉害的虚拟机。一个容器包含了一个或多个运行在沙箱里的进程。你可以限制每个容器的CPU和内存等资源。常见的容器技术有Docker和Solaris Zones.

    55679b6f4317f1e9e6a398ed50bd0ba4.png
      • 为了使用这种模式,你要把你的服务打包成一个容器镜像,容器镜像包含了一个完整的linux文件系统,服务本身的代码,相关的依赖等,一切的目的都是为了让这单个服务跑起来。比如你要打包一个java应用的容器镜像,你可能就需要一个java运行时,一个Tomcat,以及你编译后的jar包。
      • 当你需要在一个机器上运行多个容器的时候,你可能就需要服务编排工具了,例如Kubernetes 或者 Marathon。它基于容器对资源的需求以及现在剩下的资源,来决定容器到底放哪里。
      • 优势
        • 和VM一样,隔离了你的每个服务实例。
        • 和VM一样,封装了你使用的技术,容器可以不关心细节就部署。
        • 不同于VM,容器更轻,构建也更快,启动也更快.
      • 劣势
        • 容器经常部署在按VM数量收费的IaaS上,也就是说,你可能要花额外的钱。
    • 容器和VM的边界正在慢慢消失,两者正在互相靠拢。

    Serveless部署

    • AWS Lambda就是一个非常典型serveless部署,他支持你用各种语言写代码,这些代码作为一个函数,可以直接响应请求或事件。AWS会帮你解决下面的机器、内存等物理需求,你只需要关心业务逻辑就好了。
    • 一个Lambda函数是一个无状态服务,它可以直接和AWS其他的服务交互,比如当S3插进来一个新东西的时候,可以让一个函数响应并做后处理。函数还可以调用其他三方服务
    • 你有这么些方法可以调用一个函数
      • 直接通过你的服务来请求。
      • 通过AWS其他服务产生的事件触发。
      • 提供给AWS的Api gateway来提供HTTP服务。
      • 周期性的运行,基于一种cron的时间表。
    • 你能看到,AWS Lambda是一种非常方便的部署微服务的方式,并且它还基于请求收费,你只需要为你的使用量付费。你也不用关心底层的IT基础设施.
    • 劣势
      • 它不适合用来做长时间运行的服务,比如要从某个消息代理持续消费消息.
      • 请求必须在300秒以内完成.(AWS的限制吧)
      • 服务必须无状态,而且上一次函数调用和下一次函数调用很可能不在一台机器上。

    7 从一个单应用重构为微服务

    • 你最好不要使用“Big Bang”策略,也就是完全重写你的服务。既危险又耗时。
    • 你可以增量性地重构你的应用,你可以逐渐地构建一个基于微服务的新应用,和你的原来应用同时运行。随着时间的推移,所有的功能都被慢慢的从原应用迁移到微服务。

    策略1 停止挖坑

    • 不要继续把这个monolithic的天坑继续挖了,如果要加新功能,不要加到这个大应用里。你把新需求用微服务的模式来做。

    823e56be34dffa2542f5c9157dcc64a0.png
    • 如图,你新加了一个request router,把新功能的请求路由到你的新微服务里,老功能路由到老monolithic应用里。有点像API网关。
    • 你还加了一坨胶水代码,其实就是为了新老服务之间互相调用,因为他们之间也可能有交互。你可以用RPC、直接访问数据库、访问老数据库同步过来的数据等方式来实现这种调用。
    • 策略优势:它阻止了原应用变得更加难以维护。新开发的服务可以独立地开发和部署。你可以立即开始享受微服务带给你的好处。
    • 但这个策略没有对原应用做任何优化,你需要看策略2来如何改造原应用。

    策略2 分离前后端

    • 这个策略主要思路是,帮你分离展示层和业务逻辑层以及数据访问(DAO)层,从而做到让原来的monolithic应用缩小一些。通常一个典型的企业级应用有这些组件层:
      • 展示层:处理HTTP请求和展示web界面的组件们。
      • 业务逻辑层:应用实现业务逻辑的核心组件们。
      • 数据访问层:应用访问数据和消息代理的基础组件们。
    • 有一种常见的做法,你可以把你的应用按照下图,拆分成两个子应用:

    139b9bf06fb9264e2cf458fc5da8183c.png
      • 一层子应用包括了展示层。
      • 另一层子应用包含了业务逻辑和数据访问。
    • 策略优势
      • 它让你能够单独地部署和扩容两个应用,它们各自都可以快速迭代
      • 由于业务逻辑层和数据访问层单独抽离了一个应用,你的新微服务现在可以调用这坨UI无关的服务了。
    • 然而这个策略仍然只是一个部分解决方案,有可能拆分后两个应用还是会变成难以维护的monolithic应用,所以你还需要看策略3。

    策略3 抽取服务

    • 这个策略就是要把现有的在你原应用里的模块转换成单独的微服务。每次你抽出来一个新的微服务,原应用就变小了。只要你抽得足够多,原来的这个大应用就会消失或者干脆也变成一个微服务。
    • 转换成微服务的优先级
      • 首先你最好先抽象容易抽象的模块,这样你就能先积累抽象微服务的经验
      • 然后你应该优先抽取能给你带来最大收益的模块,所以你需要给你的模块排一个优先级。
      • 你还可以先抽象要特别的物理资源的模块,比如某个模块特别需要内存数据库,你可以先抽这个模块,然后把它放到内存比较大的环境里。
      • 抽象模块的粒度,可以按照这样一个简单原则:比如某个模块和其他的模块的交流都可以通过异步消息完成,那么这个模块就可以抽出来。
    • 如何抽取一个模块
      • 首先要定义抽出来的模块如何和系统进行交互,通常是一组双向的API。但通常都比较难,因为这种API会和系统耦合得比较多。用了Domain Model pattern 的就更难重构了。
      • 一旦你实现了粗粒度的接口,你就要把模块抽出来做一个单独的服务了。这时候为了同心,你还需要使用IPC机制。

    b16aa4eb6bd8dfed491b7a35870ba721.png
      • 在上面的例子中,模块Z是要被抽象出来的模块。它的组件被模块X和模块Y使用了,所以
        • 第一步就是要定义出一组粗粒的API来让X和Y通过API和Z交互。
        • 第二步就是把模块弄成单独的服务。这时候你需要IPC通信来完成他们之间的跨服务调用。
      • 你甚至可以按照新的API来重新写这个抽象的服务。你每抽出来一个服务,你就朝着微服务方向前进了一步,随着时间推移,你的原应用终将消散,而你就把它演进成了一套微服务。
    展开全文
  • 如何实现微服务的自动扩展 前面讲了一些关于自动扩展的理论知识,但如何实现自动扩展,并不是三言两语就能够说得清楚的。特别是为了实现前面提到的那些自动扩展的模式及策略,在操作系统级别方面会需要大量的执行...

    如何实现微服务的自动扩展

    前面讲了一些关于自动扩展的理论知识,但如何实现自动扩展,并不是三言两语就能够说得清楚的。特别是为了实现前面提到的那些自动扩展的模式及策略,在操作系统级别方面会需要大量的执行脚本。在自动扩展方面,SpringCloud框架也并没有给出确切的答案。

    随着微服务架构的流行,以Docker等为首的容器技术开始火热发展。Docker 是实现自动扩展非常好的基础,因为它提供了一个统一-的容 器处理方式,而不管微服务所使用的技术如何。它还帮助用户隔离微服务,以避免相邻的服务之间产生资源的竞争。

    但是,Docker 和脚本只能部分解决问题。在大规模Docker部署的情况下,仍然需要回答如下问题。

    ●如何管理数千个容器?

    ●如何监控他们?

    ●在部署工件时,如何应用规则和约束?

    ●如何确保能够正确地利用容器来获得资源效率?

    ●如何确保至少有一定数量的最小实例正在运行?

    如何确保依赖服务正常运行?

    ●如何进行滚动升级和优雅的迁移?

    ●如何回滚错误的部署?

    所有这些问题都指出需要有一个解决方案来解决以下两个关键功能。

    ●一个容器抽象层,在许多物理或虚拟机上提供统一的抽象 。

    ●容器编排和初始化系统在集群抽象之上智能管理部署。

    本节将会重点讨论这两点。

    微服务架构开发实战:如何实现微服务的自动扩展?

    容器编排

    容器编排工具为开发人员和基础架构团队提供了一个抽象层来处理大规模的集装箱部署。容器编排工具提供的功能因供应商而异。然而,他们都提供了共同的功能,其中包括发现、资源管理、监控和部署。

    1.容器编排的重要性

    编排很重要,是因为在微服务的架构里面,应用程序被拆分成不同的微服务应用,因此需要更多的服务器节点进行部署。为了正确管理微服务,开发人员倾向于为每个虚拟机部署一个微服务 ,这在一定程度上:降低了资源利用率。在很多情况下,这会导致CPU和内存的过度分配。

    在大型系统的部署中,微服务的高可用性要求迫使运维人员会添加越来越多的服务实例以实现冗余。实际上,虽然它提供了所需的高可用性,但这会导致未充分利用的服务器实例。一般来说,与单一应用程序部署相比,微服务部署需要更多的基础设施。由于基础设施成本的增加,反而令许多组织看不到微服务的价值。如图14-9 所示,为了实现系统的高可用性,每个微服务都会部署多个实例。

    微服务架构开发实战:如何实现微服务的自动扩展?

    为了解决图14-9 中所述的问题,首先需要一个能够执行以 下操作的工具。

    ●自动执行一些活动。例如,高效地将容器分配给基础设施,这对开发人员和管理员来说是透明的。

    ●为开发人员提供一个抽象层,以便他们可以将其应用程序部署到数据中心,而无须关心到底应用是要使用哪台机器。

    可以是最少的人为交互。

    ●通过最大限度地利用可用资源来高效构建、部署和管理应用程序。

    容器正是能够胜任上述工作的有力工具。使用容器,就可以以统一的方式来处理应用程序, 而无须关心微服务具体是使用了哪种技术。

    2.容器编排的工作职责

    典型的容器编排工具有助于虚拟化- -组计算机并将其作为- -个集群进行管理。容器协调工具还有助于将工作负载或容器移动到对用户透明的机器上。

    对于容器编排,业界并没有统-的术语,常见的称呼有容器编排、集群管理、数据中心虚拟化、容器调度、容器生命周期管理、数据中心操作系统等。

    容器编排工具是为了帮助自助服务和配置基础设施,而不是要求基础设施团队按照预定义的规格分配所需的机器。在这种自动化的容器编排方法中,机器不再是预配置并预先分配给应用程序。

    一些容器编排工具还可以帮助跨多个异构机器,甚至可以跨多个虚拟化数据中心,并创建-一个弹性的私有云式基础架构。

    容器编排工具目前没有标准的参考模型。因此,不同的供应商可能实现的功能各不相同。

    容器编排软件一般都会具备以下关键功能。

    ●集群管理:将一个虚拟机和物理机集群作为- -台大型机器进行管理。这些机器在资源能力方面可能是异构的,但基本上还是以Linux 为主要操作系统的机器。这些虚拟集群可以在云端,也可以是在本地,或者是两者的组合。

    ●自动部署:它支持应用程序容器的多个版本,并支持在大量集群机器上进行滚动升级。这些工具也能够处理错误,并且可以回滚到可用的版本。

    ●可伸缩性:这样可以根据需要处理应用程序实例的自动和手动可伸缩性,并将其作为主要目标进行优化利用。

    ● 运行状况监控:适用于管理集群、节点和应用程序的运行状况。它可以从集群中删除有故障的机器和应用程序实例。

    ●基础架构抽象:开发者不用担心关于机器、容量等。这完全是容器编排软件来决定如何计划和运行应用。这些工具还从开发者中抽象出机器的细节,如容量、利用率和位置等。对于应用程序所有者来说,这相当于- - 台几乎可以无限容量的大型机器。

    ● 资源优化:这些工具的固有行为是以高效的方式在一组可用机器上分配容器工作负载,从而降低成本,并提高机器的利用率。

    ●资源分配:根据应用程序开发人员设置的资源可用性和约束来分配服务器。资源分配将基于这些约束(如关联性规则、端口要求、应用程序依赖性、运行状况等)。

    ●服务可用性:确保服务在集群中的某处运行。在发生机器故障的情况下,容器编排通过在集群中的某个其他机器上重新启动这些服务来自动处理故障。

    ●敏捷性:敏捷性工具能够快速将工作负载分配给可用资源,或者在资源需求发生变化时将工作负载移至机器上。此外,还可以根据业务关键性、业务优先级等设置约束来重新调整资源。

    ●隔离:这些工具中有一些提供了开箱即用的资源隔离功能。因此,即使应用程序没有进行容器化,也可以实现资源的隔离。

    3.资源分配的常用算法

    从简单算法到具有机器学习和人工智能的复杂算法,在容器编排中,资源分配会使用各种算法。

    比较常用的算法有传播( Spread)、装箱( Bin Packing )和随机( Random)。针对应用程序设置的约束,来设置基于资源可用性的默认算法。

    图14-10~图14-12 显示了这些算法是如何用部署填充到可用的机器上的。在这种情况下,这里用两台机器进行演示。

    微服务架构开发实战:如何实现微服务的自动扩展?

    资源分配的3种常用策略解释如下。

    ●传播:这将工作负载平均分配到可用的机器上,如图14-10所示。

    ●装箱: 这将试图通过机器填充机器,并确保机器的最大利用率。在按需付费的云服务中,装箱算法是特别好的。

    随机:随机选择机器并在随机选择的机器上部署容器,如图14-12所示。

    微服务架构开发实战:如何实现微服务的自动扩展?

    随着科技的发展,机器学习和协作过滤等手段可以更好地提高效率。例如,可以将未分配的资源分配给高优先级的任务( 这些任务意味着有更高的收益),以便充分利用现有资源,提高创收。

    4.与微服务的关系

    微服务的基础设施(如果配置不当)很容易导致基础设施过大,本质上导致成本的增加。正如前面部分所讨论的那样,在处理大规模微服务架构系统时,具有容器编排工具的类似云的环境对于实现成本效益至关重要。

    在Spring Cloud 项目中利用Spring Boot来构建微服务,是利用容器编排技术的理想工具。由于基于Spring Cloud的微服务并不关心具体的位置,因此可以将这些服务部署到集群中的任何位置。

    每当出现服务时,它都会自动注册到服务注册中心并通告其可用性。另外,消费者总是寻找服务注册表来发现可用的服务实例。这样,应用程序就可以支持完整的流体结构,而无须预先部署拓扑结构。使用Docker能够在抽象运行时,以便服务可以在任何基于Linux的环境中运行。

    5.与虚拟化技术的关系

    容器编排解决方案在许多方面与传统的服务器虚拟化解决方案有着比较大的差异。容器编排解决方案作为应用程序组件,运行在虚拟机或物理机器之上。

    常用的容器编排技术

    1. Docker Swarm

    Docker Swarm是Docker的本地容器编排解决方案。Swarm 提供与Docker的本地和更深层次的集成,并有着与Docker的远程API兼容的API。它在逻辑上将- -组 Docker主机分组,并将它们作为一个大型的Docker虚拟主机进行管理。应用程序管理员和开发人员无须决定容器是在哪个主机上部署,这个决策将被委托给Docker Swarm。它将根据分组打包和扩展算法决定使用哪个主机。

    由于Docker Swarm基于Docker的远程API,现有Docker用户的学习曲线与其他任何容器业务流程工具相比要少得多。然而,Docker Swarm是市场上较新的产品,仅支持Docker容器。

    Docker Swarm使用管理器( manager)和节点( node)的概念。管理员通过管理器来与Docker容器进行交互和调度。节点则是Docker容器部署和运行的地方。

    2. Kubernetes

    Kubermetes ( k8s )来自Google 的工程设计,使用Go语言编写,并正在Google进行大规模部署的测试。与Swarm类似,Kubernetes帮助管理跨集群节点的容器化应用程序。它有助于自动化容器部署和容器的调度与可伸缩性。它支持许多有用的开箱即用功能,如自动逐步展开、版本化部署和容器弹性管理等。

    Kubermetes 体系结构具有主节点( master)、节点(node)和pod等概念。主节点和节点一起被称为Kubernetes集群。主节点负责跨多个节点分配和管理工作负载,节点就是虚拟机或物理机器。

    节点既可以被进一-步分割成pod,也可以托管多个pod。一个或多个容器在一个pod内分组并执行。

    pod还有助于管理和部署共存服务以提高效率。Kubernetes 也支持标签的概念作为键值对,以便查询和查找容器。标签是用户定义的参数,用于标记执行常见类型工作负载的某些类型的节点,如前端Web服务器等。

    部署在集群上的服务将获得- - 个IP/DNS用来访问该服务。Kubernetes 对Docker有开箱即用的支持。然而,Kubernetes 的学习曲线会比Docker Swarm更多。作为OpenShift 平台的一部分, RedHat为Kubernetes提供商业支持。

    3. Apache Mesos

    有关ApacheMesos的介绍,最早可追溯到BenjaminHindman等所写的技术白皮书Mesos:APlatform for Fine-Grained Resource Sharing in the Data Center (可以在线查看该文章htp://mesos.berkeley.edu/mesos_ tech_ reportpdf )。后来Benjamin Hindman加入了Twitter, 负责开发和部署Mesos。再后来Benjamin Hindman离开Twitter而去了Mesosphere, 着手建设并商业化以Mesos为核心的DC/OS (数据中心操作系统)。

    Mesos是Apache下的开源分布式资源管理框架,它被称为是分布式系统的内核,使用内置Linux内核相同的原理,只是在不同的抽象层次。该Mesos内核运行在每个机器上,在整个数据中心和云环境内向应用程序(如Hadoop、Spark、 Kafka、 Elasticsearch 等)提供资源管理和资源负载的API接口。

    Apache Mesos具备以下特性。

    ● 线性可扩展性:业界认可的可扩展到10000个节点。

    ●高可用性:使用ZooKeeper实现master和agent的容错,且实现了无中断的升级。

    支持容器:原生支持Docker容器和AppC镜像。

    ●可拔插的隔离:对CPU、内存、磁盘、端口、GPU和模块实现自定义资源的一-等( first class )隔离支持。

    ●二级调度:支持使用可插拔调度策略来在相同集群中运行云原生和遗留的应用程序。

    • API: 提供HTTP API在操作集群、监控等方面开发新的分布式应用程序。
    • Web界面:内置Web界面查看集群的状态,并可以导航containersandbox(容器沙箱)
    • 跨平台:可以在Linux、OSX和Windows 上运行,并且与云服务提供商无关。

    Mesos与以往的解决方案稍有不同。它更多的是依靠其他框架来管理工作负载执行的资源管理器。它位于操作系统和应用程序之间,提供了- -个逻辑的机器集群。

    Mesos是一个分布式系统内核,将多台计算机逻辑分组并将其虚拟化为一台 大型机器。它能够将许多异构资源分组到一个统一资源集群 上,在这个集群上可以部署应用程序。基于这些原因,Mesos也被称为在数据中心建立私有云的工具。

    Mesos具有主节点和从节点的概念。与早期的解决方案类似,主节点负责管理集群,而从节点负责运行工作负载。它在内部使用ZooKeeper进行集群协调和存储,也支持框架的概念。这些框架负责调度和运行非集装箱应用程序和容器。Marathon、 Chronos 和Aurora是应用程序调度和执行的流行框架。Netflix 的Fenzo是另一个开源的Mesos框架。有趣的是,Kubernetes 也可以用作Mesos框架。

    Marathon支持Docker容器,以及非容器化的应用程序。Spring Boot可以直接配置在Marathon中。Marathon提供了许多开箱即用的功能,如支持应用程序依赖项用于扩展和升级服务的应用程序分组、实例的启动和关闭、滚动升级、回滚失败升级等。

    Mesosphere作为DC/OS平台的一部分, 为Mesos和Marathon提供商业支持。

    总结

    Spring Cloud并没有提供现成的处理自动扩展的方案,但结合目前市面上常用的容器编排技术(如上文提到的Docker Swarm、Kubermetes、Apache Mesos等),能够方便地实现服务的自动扩展。

    自动扩展在微服务架构中是一个相对复杂的问题,学习成本相对也比较高。由于自动扩展并非是Spring Cloud的核心话题,因此本文也只是给出了一些基本的概念和思路,不做深入的探讨。如果读者对这方面感兴趣,也可以自行查阅相关资料。以下是一些常用的学习链接地址。

    Docker Swarm: htps://cs.docker.com/swarm

    ● Kubernetes : htps://kubermetes.io/docs/home/.

    ●Apache Mesos: htp:/m/esos.apache .org/documentation/latest。

    本篇文章内容给大家讲解的是如何实现微服务的自动扩展

    1. 下篇文章给大家讲解的是微服务的高级主题一 熔断机制;
    2. 觉得文章不错的朋友可以转发此文关注小编;
    3. 感谢大家的支持!
    展开全文
  • 微服务

    2018-10-15 21:56:51
    微服务实战(一):微服务架构的优势与不足 【编者的话】本文来自Nginx官方博客,是微服务系列文章的第一篇,主要探讨了传统的单体式应用的不足,以及微服务架构的优势与挑战。正如作者所说,微服务架构更适合用于...
  • 微服务系统,目前比较流行的是采用spring cloud/dubbo这些微服务框架做前后端的分离开发模式。横向把前端和后端从人员架构上分离开来,用于减少对人员的综合素质要求。现在前端的技术发展日新月异,已经很难做到一个...
  • 微服务
  • 微服务实战(六):选择微服务部署策略 【编者的话】这篇博客是用微服务建应用的第六篇, 第一篇 介绍了微服务架构模板,并且讨论了使用微服务的优缺点。随后的文章讨论了微服务不同方面:使用API网关,进程间通讯...
  • 前端微服务

    2021-09-13 11:50:28
    文章目录微服务介绍微服务的优点:微服务插件——qiankun.jsqiankun介绍代码演示(Vue+ Qiankun+React+static+Angular) 微服务介绍 前端微服务是一种多个团队通过独立发布功能的方式来共同构建现代化 web 应用的...
  • 微服务体系

    万次阅读 2019-12-19 17:14:04
    标题微服务体系 微服务 ...是一种将单应用程序作为一套小型服务开发的方法,每种应用程序都在其自己的进程中运行,并采用轻量级的通讯机制(TCP)进行通信。这些服务是围绕业务功能构建的,...
  • 微服务介绍

    2021-03-30 17:49:23
    微服务 单体架构 经典的3层模型 mvc 表示层:用于和用户交互,...微服务架构的风格,就是将单一程序开发成一个微服务,每个服务运行在自己进程中,并使用轻量级机制通信,一般是RESTFUL风格 服务按业务划分 服务之间
  • 基于阿里云容器服务的微服务实践 - Part 1. 微服务与Docker作者:chszs,未经博主允许不得转载。经许可的转载需注明作者和博客主页:http://blog.csdn.net/chszs从2012年起,在IT领域逐渐能听到微服务...
  • 关于麦洛 麦洛是 Java 开发者和技术爱好者。 对 Java 相关技术特别感兴趣,包括 javaee、 Spring系列、 微服务等 ...
  • 全网最新《微服务架构2.0》课程旨在推动并普及微服务架构思想,技术选型紧跟阿里系开源生态方案及服务网格等技术,规范微服务开发流程,让您真正体会互联网微服务开发的独特魅力。 本视频教程为之前《微服务解决复杂...
  • 一个微服务应用由上百个服务构成,服务可以采用不同语言和框架分别写就。每个服务都是一个单一应用,可以有自己的部署、资源、扩展和监控需求。例如,可以根据服务需求运行若干个服务实例,除此之外,每个实例必须有...
  • 微服务实战系列文章

    千次阅读 2018-01-18 17:39:21
    本系列文章为 dockone.io 首发,转载请标明出处,以...也许你正在开发一个大型、复杂单体式应用,日常开发和部署经验非常缓慢和痛苦,而微服务看起来是远方一个极乐世界。幸运的是,有可以参考的脱离苦海的策略,本篇
  • 微服务随笔

    2019-01-22 17:43:51
     1)、SpringBoot专注于快速方便的开发单个个体微服务。  2)、SpringCloud是关注全局的微服务协调、整理、治理的框架,它将SpringBoot开发的单体整合并管理起来。    3)、SpringBoot可以离开SpringCloud...
  • java gzip 机密1.简介 安全性是现代软件系统中异常重要的元素。 它本身就是一个巨大的主题,它包含许多不同的方面,因此切勿事后思考。... 如果没有,您最好雇用一名,因为开发人员的专业知识在...
  • 微服务架构的多种部署模式 ...以微服务架构开发的程序,经常涉及到多个服务组成,后端的网关模块,用户模块,日志模块,业务模块等,还有前端Node.js模块。以笔者所在公司为例,每次部署服务时都要互相之间沟...
  • 轻量级微服务架构

    2021-07-13 17:00:53
    目录微服务架构设计概述为什么需要微服务架构传统架构的问题 微服务架构设计概述 自从Martin Fowler(马丁)在2014年提出了Micro Service(微服务)的概念之后,业界就卷起了一股关于微服务的热潮,大家讨论多年的...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,263
精华内容 905
关键字:

微服务开发沙箱