微服务部署

Posted 左直拳

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了微服务部署相关的知识,希望对你有一定的参考价值。

自己动手,丰衣足食。看上去很琐碎繁杂,其实动手部署一次就好。

现在计算机软件开发,发展出新花样。其中有前后端分离,和微服务。其实这2样东东,对软件产品本身并没有什么帮助,软件产品中应用了这些架构,并不会比没有应用它们的产品更优秀。甚至,还会有一些反作用。

比如,前后端分离,数据只能通过请求获取,服务器处理并直接输出这种模式就没有了(websocket除外)。异步操作在数据量大的情况下体验比较好,如果只有一丁点数据,其实直接输出效果更佳。与前后端分离相伴生的单页面应用,加大了编码的复杂性,需要考虑以往WEB开发根本不存在的组件区隔性,数据的重置等问题。

又比如微服务,有些人认为微服务会提高性能。其实,微服务与性能提升并没有什么必然联系。微服务的作用,是将一个复杂问题,分解为若干个相对简单的小问题,而总体功能不变。然后每个服务,独立开发,独立部署,独立配置,可以应用不同的技术栈。这其中,可能有助于功能复用,业务划分。当然啦,微服务是分布式部署,有些关键性服务单独部署在很强的服务器上,的确会有助于提升部分性能。但是,微服务间通过各种管理、转发、网络连接,又抵消了部分性能。而且部署起来,比之前要复杂得多。这种工作方式,甚至会使得开发人员不知道如何部署,于是美其名曰,不用关心如何部署。专业的事情由专业的人来做,我们有自动化部署脚本,打包,上传,部署,一键搞定,巴拉巴拉巴拉。。。

但这种模式,需要一个24小时待命的全职运维人员。如果只是某个程序员兼职,想部署、更新就麻烦。如果该程序员本身很忙,就更麻烦。

更麻烦的是,部署上去以后发现有问题。哪个环节出了问题?怎么调试?本来是程序员一个人的事情,现在要多方沟通(其实往往是多方扯皮)。考究沟通能力。没错,沟通也是程序员基本功之一:

为啥我这个服务好像没有更新到?
不可能!只要你提交了代码就会更新到,没提交就不会更新咯。
为啥我这个服务在本地开发没有问题,但部署上去以后就不行?
哦,开发环境跟docker容器不一样。you know,docker本身也是一个环境。

怪不得,要强调DevOps,大家要通力合作,精诚团结。

总的来说,采用微服务与前后端分离打造出来的产品,并不比原先的产品更好,而是由于它们将一个产品分拆成了独立块,每一块都可以独立开发,独立部署,独立配置,使用不同技术栈,能够并行开发,提高了开发效率。提升的不是产品,是产品的打造速度。但是,这个速度是以增加技术复杂性,加大人员投入来换取的。

话说,我这段时间参加的项目,就是跑在微服务架构上的。使用的技术栈,工具,整理了一下,如下:

1、spring cloud,开发框架
2、nacos,微服务管理框架
3、docker,微服务容器
4、统信uos,生产环境操作系统

这里面,最复杂的应该是spring cloud,但最令我感到新奇的是nacos。

nacos,用于管理微服务。包括注册,监管,消息转发,等等。消息转发是指,比如前端请求转发到相关微服务;微服务之间相互调用之类。就是它接管了微服务。可能与之类似的是K8吧。每个微服务的配置里面,都指向这个nacos,所以启动的时候,会到nacos注册。

假如我现在要部署一个服务到docker,该怎么处理呢?

1、相关代码
发布服务的时候,需要指向nacos地址,nacos的命名空间。命名空间管理各种配置。之前将配置写在配置文件,配置文件刚开始时是XML,后来嫌烦,开始约定重于配置,简化配置文件。现在又将配置变成了外挂。更改配置,只需在nacos提供的WEB页面上进行,越来越方便了。

假设有一个采用微服务框架的程序,A服务是其中一个微服务。

1)微服务框架的的 /pom.xml
里面定义了开发环境,生产环境。每个环境都指向了各自的nacos,以及一些配置。例如开发环境,

<properties>
    <!--当前环境-->
    <profile.name>sb-dev</profile.name>
    <!--Nacos配置中心地址-->
    <config.server-addr>192.168.0.218:8848</config.server-addr>
    <!--Nacos配置中心命名空间,用于支持多环境.这里必须使用ID,不能使用名称,默认为空-->
    <config.namespace>sb-dev</config.namespace>
    <!--Nacos服务发现地址-->
    <discovery.server-addr>192.168.0.218:8848</discovery.server-addr>
    <!--微服务注册服务地址网段-->
    <discovery.server-ip>192.168.0</discovery.server-ip>
    <!--zipkin服务地址-->
    <zipkin.base-url>http://192.168.0.218:9411/</zipkin.base-url>

    <!--    端口配置-->
    <!--        网关-->
    <getway.server.port>8888</getway.server.port>
    <!--    微服务A  -->
    <sb.server.port>8192</sb.server.port>
</properties>

2)微服务A的配置文件bootstrap.yml

server:
  tomcat:
    uri-encoding: UTF-8
    max-threads: 1000
    min-spare-threads: 30
  port: $sb.server.port #这里采纳上一pom.xml里的zhfz.dzzhyj.server.port

…… 省略 ……

  cloud:
    #手动配置Bus id,
    bus:
      id: $spring.application.name:$server.port
    nacos:
      config:
        namespace: $config.namespace
        refreshable-dataids: common.properties
        server-addr: $config.server-addr
        ext-config[0]:
          data-id: common.properties
        ext-config[1]:
          data-id: mydb.yml
          group: SB_GROUP
        ext-config[2]:
          data-id: redis.properties
        ext-config[3]:
          data-id: rabbitmq.properties
        ext-config[4]:
          data-id: minio.properties
        ext-config[5]:
          data-id: file_storage.yml
          group: SB_GROUP
        ext-config[6]:
          data-id: ftpqx.yml
          group: SB_GROUP
        ext-config[7]:
          data-id: rainfall.yml
          group: SB_GROUP
        ext-config[8]:
          data-id: simsunttc.yml
          group: SB_GROUP
      discovery:
        namespace: $config.namespace
        server-addr: $discovery.server-addr

2、发布程序jar包

mvn clean package -Dmaven.test.skip=true -Psb-dev -pl sb-server -am

其中sb-dev是环境名称,发布项目sb-server。

-pl --projects Build specified reactor projects instead of all projects
选项后可跟随groupId:artifactId或者所选模块的相对路径(多个模块以逗号分隔)

-am --also-make If project list is specified, also build projects required by the list
表示同时处理选定模块所依赖的模块

-amd --also-make-dependents If project list is specified, also build projects that depend on projects on the list
表示同时处理依赖选定模块的模块

-N --Non-recursive Build projects without recursive
表示不递归子模块

-rf --resume-from Resume reactor from specified project
表示从指定模块开始继续处理

3、部署到docker
运行一段脚本,将jar部署进docker

#!/bin/bash
CLOUD_VERSION=3.0.0
SB_VERSION=1.0.0
DOCKER_BUILD_PATH=/home/user/docker/buildtag
DATE=`date +%Y%m%d%H%M`
#SB_NAMES=("sb-server1" "sb-server2" "sb-server3" "sb-server4") #一次部署多个
SB_NAMES=("open-cloud-zhfz-dzzhyj-server") #只部署一个

for (( i = 0 ; i < $#SB_NAMES[@] ; i++ ))
do
    cd $DOCKER_BUILD_PATH/$SB_NAMES[$i]/
    if [[ -f $SB_NAMES[$i].jar ]]; then
        if docker ps -a | grep $SB_NAMES[$i]; 
            then
                docker rm -f $SB_NAMES[$i]
                echo "Remove Docker Container: $SB_NAMES[$i]"
        fi
        docker build -t $SB_NAMES[$i]:$SB_VERSION .
        docker run -d --network host --memory 5120m -e JAVA_OPTS='-Xmx4096m'  --name $SB_NAMES[$i] $SB_NAMES[$i]:$SB_VERSION
        echo "docker run $SB_NAMES[$i]-$SB_VERSION";
    else
        echo "file $SB_NAMES[$i].jar not exist";
    fi
done

以上是关于微服务部署的主要内容,如果未能解决你的问题,请参考以下文章

微服务实战:选择微服务部署策略

如何在Kubernetes上进行微服务部署

docker微服务部署之:Rancher管理部署微服务

Docker微服务部署

将微服务部署到 Cloud Foundry

微服务部署架构简介