• 项目发布


    微服务


    单体架构

    单体架构,是指将开发好的项目打成war包,然后发布到tomcat等容器中的应用。

    假设你正准备开发一款与Uber和滴滴竞争的出租车调度软件,经过初步会议和需求分析,你可能会手动或者使用基于Spring Boot、Play或者Maven的生成器开始这个新项目,它的六边形架构是模块化的

    应用核心是业务逻辑,由定义服务、领域对象和事件的模块完成。围绕着核心的是与外界打交道的适配器。适配器包括数据库访问组件、生产和处理消息的消息组件,以及提供API或者UI访问支持的web模块等。

    最终它还是会打包并部署为单体式应用。具体的格式依赖于应用语言和框架。例如,许多Java应用会被打包为WAR格式,部署在Tomcat或者Jetty上,而另外一些Java应用会被打包成自包含的JAR格式,类似的,Rails和Node.js会被打包成层级目录


    微服务

    微服务架构是一种架构模式,它提倡将单一应用程序划分成一组小的服务,服务之间互相协调、互相配合,为用户提供最终价值。每个服务运行在其独立的进程中,服务与服务间采用轻量级的通信机制互相沟通(通常是基于HTTP的RESTful API)。

    每个服务都围绕着具体业务进行构建,并且能够被独立地部署到生产环境、类生产环境等。另外,应尽量避免统一的、集中式的服务管理机制,对具体的一个服务而言,应根据业务上下文,选择合适的语言、工具对其进行构建。

    微服务是一种架构风格,一个大型复杂软件应用由一个或多个微服务组成。系统中的各个微服务可被独立部署,各个微服务之间是松耦合的。每个微服务仅关注于完成一件任务并很好地完成该任务。在所有情况下,每个任务代表着一个小的业务能力。


    优点

    • 服务组件化

      每个服务独立开发, 部署, 有效避免一个服务的修改引起整个系统重新部署


    • 技术栈灵活

      约定通信方式, 使得服务本身功能实现对技术要求不再那么敏感,每个服务的请求会发到注册中心,注册中心交给API GATEWAY, 通过路由找到相应的服务给出响应


    • 独立部署

      每个微服务独立部署, 加快部署速度, 方便扩展


    • 扩展性强

      每个微服务可以部署多个, 并且有负载能力


    • 独立数据

      每个微服务有独立的基本组件,例如数据库, 缓存等


    缺点

    • 沟通成本
    • 数据一致性
    • 运维成本
      • 大量服务如何治理
      • 如何部署
      • 如何监控
      • 数据和事务
    • 内部架构复杂性

    微服务问题


    • 微服务间如何通信?

      REST API, RPC, MQ


    • 微服务如何发现彼此

      前端接收用户的http/https请求, 交给负载均衡器, 负载均衡器将请求发送给下面的某一个网关, 网关与注册中心 通信,注册中心是一个生产者消费者模型, 所有的服务的生产者消费者都存在这里, 网关中的请求是消费者, 通过注册中心寻找请求对应的生产者,生产者提供相应的响应, 如果配置比较多, 则所有服务的配置会交给配置中心统一管理配置


    • 组件之间如何调用关系

      根据用户的访问顺序确定调用关系(先看商品,下订单,支付)


    • 哪个服务作为整个网站的入口

      前端, 接收用户的请求, 发送给网关

      网关, 服务端的入口,接收前端的请求 和 发送响应给负载均衡器并交给前端


    • 哪些微服务需要对外访问

      前端和负载均衡器需要通信,所以前端的端口, 负载均衡器的端口需要暴露


    • 微服务怎么部署, 更新, 扩容

      以java为例, 通过jar包的形式进行部署, 更新, 扩容


    • 区分有状态应用和无状态应用

      一般k8s部署, 都是部署无状态应用,


    • 为什么要有注册中心(Eureka, Nacos)

      记录微服务多个副本的接口地址

      实现一个微服务多个副本的负载均衡

      判断微服务副本是否可用


    项目迁移到k8s


    流程

    制作镜像 - 控制器管理pod - 暴露应用 - 对外发布应用 - Pod数据持久化 - 日志/监控


    第一步: 制作镜像(3层结构)

    基础镜像: centos, ubuntu

    运行环境/中间件镜像: jdk, php (+基础镜像)

    项目镜像: 基础镜像 + 运行环境 + 项目代码


    第二步: 控制器管理pod

    • Deployment: 无状态部署
    • StatefulSet: 有状态部署
    • DaemonSet: 守护进程部署
    • Job & CronJob: 批处理

    第三步: 暴露应用

    通过Service

    • Service 定义了Pod的逻辑集合和访问这个集合的策略
    • Service 引入为了解决Pod的动态变化, 提供服务发现和负载均衡

    第四步: 对外发布应用


    通过 Ingress

    • 通过Service关联Pod
    • 基于域名访问
    • 通过Ingress Controller 实现Pod的负载均衡

    第五步: Pod数据持久化(数据卷/PVC)

    容器部署过程中一般有3类数据

    • 启动时需要的初始数据, 可以是配置文件
    • 启动过程中产生的临时数据, 该临时数据需要多个容器间共享
    • 启动过程中产生的持久化数据

    第六步: 日志/监控

    • Filebeat + ELK
    • Prometheus + Grafana

    传统部署和k8s部署的区别


    传统部署是上传war/jar包, k8s部署是上传镜像


    传统部署


    k8s部署


    部署spring Cloud微服务项目


    示例代码: https://gitee.com/chen1219/simple-microservice.git

    代码分支说明

    • dev1 交付代码
    • dev2 编写Dockerfile构建镜像
    • dev3 K8s资源编排
    • dev4 微服务链路监控
    • master 最终上线


    第一步: 代码编译构建


    • 拉取镜像
    git clone -b dev1 https://gitee.com/chen1219/simple-microservice.git dev1
    git clone -b dev2 https://gitee.com/chen1219/simple-microservice.git dev2
    git clone -b dev3 https://gitee.com/chen1219/simple-microservice.git dev3
    git clone -b dev4 https://gitee.com/chen1219/simple-microservice.git dev4
    git clone -b master https://gitee.com/chen1219/simple-microservice.git master
    

    • 安装maven 和 java
    yum -y install java-1.8.0-openjdk maven
    

    • maven打包
    cd /root/dev2
    mvn clean package -Dmaven.test.skip=true
    


    • 打包完成, 每个服务的target目录下面会产生jar包
    ll eureka-service/target/ gateway-service/target/ basic-common/ order-service/order-service-biz/target/ product-service/product-service-biz/target/ stock-service/stock-service-biz/target/ portal-service/target/
    


    第二步: 将打包成的jar包构建项目镜像


    打包单一服务示例

    cd product-service/product-service-biz/
    docker build -t product .
    


    • 查看构建的镜像
    docker images
    


    构建全部镜像


    • 设置镜像仓库
    vim  /etc/docker/daemon.json 
    
    {
           "registry-mirrors": [
            "https://1nj0zren.mirror.aliyuncs.com",
            "https://docker.mirrors.ustc.edu.cn",
            "http://f1361db2.m.daocloud.io",
            "https://registry.docker-cn.com"
        ],
         "insecure-registries" : [ "172.16.240.200:5000", "172.16.240.110:8999", "172.16.240.121" ], 
         "exec-opts": ["native.cgroupdriver=systemd"],
         "log-driver": "json-file",
        "log-opts": {"max-size": "100m"}
    }
    
    systemctl restart docker
    

    • 登录镜像仓库
    docker login 172.16.240.121 
    


    mkdir k8s && cd k8s
    vim docker_build.sh 
    
    #!/bin/bash
    
    docker_registry=172.16.240.121
    
    service_list="eureka-service gateway-service order-service product-service stock-service portal-service"
    service_list=${1:-${service_list}}
    work_dir=$(dirname $PWD)
    current_dir=$PWD
    
    cd $work_dir
    mvn clean package -Dmaven.test.skip=true
    
    for service in $service_list; do
       cd $work_dir/$service
       if ls |grep biz &>/dev/null; then
          cd ${service}-biz
       fi
       service=${service%-*}
       image_name=$docker_registry/microservice/${service}:$(date +%F-%H-%M-%S)
       docker build -t ${image_name} .
       docker push ${image_name} 
    done
    

    ./docker_build.sh
    

    • 查看镜像仓库


    第三步: 将项目部署到k8s环境

    172.16.240.100 k8s-master
    172.16.240.101 k8s-node01
    172.16.240.102 k8s-node02
    172.16.240.121 harbor, mysql
    


    服务编排

    https://gitee.com/chen1219/simple-microservice/tree/dev3/k8s

    https://gitee.com/chen1219/simple-microservice/blob/dev3/eureka-service/src/main/resources/application-fat.yml

    https://gitee.com/chen1219/simple-microservice/blob/dev3/gateway-service/src/main/resources/application-fat.yml

    https://gitee.com/chen1219/simple-microservice/blob/dev3/portal-service/src/main/resources/application-fat.yml

    https://gitee.com/chen1219/simple-microservice/blob/dev3/order-service/order-service-biz/src/main/resources/application-fat.yml

    https://gitee.com/chen1219/simple-microservice/blob/dev3/product-service/product-service-biz/src/main/resources/application-fat.yml

    https://gitee.com/chen1219/simple-microservice/blob/dev3/stock-service/stock-service-biz/src/main/resources/application-fat.yml


    准备数据库

    mysql> create database tb_order;
    Query OK, 1 row affected (0.01 sec)
    
    mysql> create database tb_product;
    Query OK, 1 row affected (0.00 sec)
    
    mysql> create database tb_stock;
    Query OK, 1 row affected (0.01 sec)
    
    mysql> use tb_order;
    Database changed
    mysql> source order.sql;
    
    mysql> use tb_product;
    Database changed
    mysql> source product.sql;
    
    mysql> use tb_stock;
    Database changed
    mysql> source stock.sql
    

    • 配置数据库
    spring:
      datasource:
        url: jdbc:mysql://172.16.240.121:3306/tb_stock?characterEncoding=utf-8
        username: java
        password: 123456
        driver-class-name: com.mysql.jdbc.Driver
    

    部署ingress controller

    wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/mandatory.yaml
    kubectl apply -f mandatory.yaml
    

    部署nginx-ingress

    http://m.py3study.com/Article/details/id/19809.html

    wget https://kuboard.cn/install-script/v1.17.x/nginx-ingress.yaml
    kubectl apply -f nginx-ingress.yaml
    

    部署eureka集群

    kubectl create ns ms
    kubectl create secret docker-registry registry-pull-secret --docker-server=172.16.240.121 --docker-username=admin --docker-password=Harbor12345 --docker-email=admin@ctnrs.com -n ms
    kubectl apply -f eureka.yaml
    kubectl get pods,svc -n ms
    


    • 配置本地域名解析(/etc/hosts)

      随意一个部署有eureka的节点配置本地解析就能访问

    172.16.240.101 eureka.ctnrs.com
    

    浏览器输入 http://eureka.ctnrs.com/, 可以看到eureka页面


    部署网关(gateway)

    kubectl apply -f k8s/gateway.yaml 
    

    部署前端(portal)

    kubectl apply -f k8s/portal.yaml
    

    部署product, stock, order

    kubectl apply -f k8s/stock.yaml 
    kubectl apply -f k8s/order.yaml 
    kubectl apply -f k8s/product.yaml 
    

    准备基础环境


    172.16.240.111 gitlab
    172.16.240.121 harbor
    

    1、代码版本仓库 Gitlab

    1.1 部署gitlab

    docker run -d --name gitlab --hostname gitlab.hims-portal-stg1.paic.com.cn -p 443:443 -p 80:80 -p 8022:22 --restart always -v /srv/gitlab/config:/etc/gitlab -v /srv/gitlab/logs:/var/log/gitlab -v /srv/gitlab/data:/var/opt/gitlab gitlab/gitlab-ce:12.8.8-ce.0
    

    访问地址:

    初次会先设置管理员密码 ,然后登陆,默认管理员用户名root,密码就是刚设置的。

    1.2 创建项目,提交测试代码

    https://github.com/lizhenliang/simple-microservice

    代码分支说明:

    • dev1 交付代码
    • dev2 编写Dockerfile构建镜像
    • dev3 K8S资源编排
    • dev4 增加微服务链路监控
    • master 最终上线

    拉取dev3分支,推送到私有代码仓库:

    git clone -b dev3 https://github.com/lizhenliang/simple-microservice
    git clone http://192.168.31.70:9999/root/microservice.git
    cp -rf simple-microservice/* microservice
    cd microservice
    git add .
    git config --global user.email "you@example.com"
    git config --global user.name "Your Name"
    git commit -m 'all'
    git push origin master
    

    2、镜像仓库 Harbor

    2.1 安装docker与docker-compose

    wget http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -O /etc/yum.repos.d/docker-ce.repo
    yum install docker-ce -y
    systemctl start docker
    systemctl enable docker
    
    curl -L https://github.com/docker/compose/releases/download/1.25.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
    chmod +x /usr/local/bin/docker-compose
    

    2.2 解压离线包部署

    # tar zxvf harbor-offline-installer-v1.9.1.tgz
    # cd harbor
    # vi harbor.yml
    hostname: 192.168.31.70
    # ./prepare
    # ./install.sh --with-chartmuseum
    # docker-compose ps 
    

    --with-chartmuseum 参数表示启用Charts存储功能。

    2.3 配置Docker可信任

    由于habor未配置https,还需要在docker配置可信任。

    # cat /etc/docker/daemon.json 
    {"registry-mirrors": ["http://f1361db2.m.daocloud.io"],
      "insecure-registries": ["192.168.31.70"]
    }
    # systemctl restart docker
    

    3、应用包管理器 Helm

    3.1 安装Helm工具

    # wget https://get.helm.sh/helm-v3.0.0-linux-amd64.tar.gz
    # tar zxvf helm-v3.0.0-linux-amd64.tar.gz 
    # mv linux-amd64/helm /usr/bin/
    

    3.2 配置国内Chart仓库

    # helm repo add stable http://mirror.azure.cn/kubernetes/charts
    # helm repo add aliyun https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts 
    # helm repo list
    

    3.3 安装push插件

    # helm plugin install https://github.com/chartmuseum/helm-push
    

    如果网络下载不了,也可以直接解压课件里包:

    # tar zxvf helm-push_0.7.1_linux_amd64.tar.gz
    # mkdir -p /root/.local/share/helm/plugins/helm-push
    # chmod +x bin/*
    # mv bin plugin.yaml /root/.local/share/helm/plugins/helm-push
    

    3.4 添加repo

    # helm repo add  --username admin --password Harbor12345 myrepo http://192.168.31.70/chartrepo/library
    

    3.5 推送与安装Chart

    # helm push mysql-1.4.0.tgz --username=admin --password=Harbor12345 http://192.168.31.70/chartrepo/library
    # helm install web --version 1.4.0 myrepo/demo
    

    4、微服务数据库 MySQL

    # yum install mariadb-server -y
    # mysqladmin -uroot password '123456'
    

    或者docker创建

    docker run -d --name db -p 3306:3306 -v /opt/mysql:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7 --character-set-server=utf8
    

    最后将微服务数据库导入。

    5、K8S PV自动供给

    先准备一台NFS服务器为K8S提供存储支持。

    # yum install nfs-utils
    # vi /etc/exports
    /ifs/kubernetes *(rw,no_root_squash)
    # mkdir -p /ifs/kubernetes
    # systemctl start nfs
    # systemctl enable nfs
    

    并且要在每个Node上安装nfs-utils包,用于mount挂载时用。

    由于K8S不支持NFS动态供给,还需要先安装上图中的nfs-client-provisioner插件:

    # cd nfs-client
    # vi deployment.yaml # 修改里面NFS地址和共享目录为你的
    # kubectl apply -f .
    # kubectl get pods
    NAME                                     READY   STATUS    RESTARTS   AGE
    nfs-client-provisioner-df88f57df-bv8h7   1/1     Running   0          49m
    

    6、持续集成 Jenkins

    由于默认插件源在国外服务器,大多数网络无法顺利下载,需修改国内插件源地址:

    cd jenkins_home/updates
    sed -i 's/http://updates.jenkins-ci.org/download/https://mirrors.tuna.tsinghua.edu.cn/jenkins/g' default.json && 
    sed -i 's/http://www.google.com/https://www.baidu.com/g' default.json
    
  • 相关阅读:
    ASP.NET之Cookie(坑爹的Response.Cookies.Remove)
    ASP.NET 4.0中使用FreeTextBox和FCKeditor遇到安全问题警告的解决办法
    ASP.NET用户控件操作ASPX页面(在ASPX页面捕捉用户控件的事件)
    ASP.NET页面传值之Server.Transfer
    印象中的东北特色
    Python第二周之函数及其作用域
    Python第二周之字符串,列表,元组,集合,字典
    Python第一周习题集(一)
    Python第二周习题集(一)(Craps游戏 质数 公约数 公倍数 回文质数 21根火柴游戏 验证码 后缀名 骰子随机和)
    Python第一周习题集(二)
  • 原文地址:https://www.cnblogs.com/cjwnb/p/12706875.html
Copyright © 2020-2023  润新知