Spring Boot总结(九):构建高性能的服务平台

Spring Boot总结(一):入门

Spring Boot总结(二):Spring Boot中使用数据库

Spring Boot总结(三):Spring Boot界面设计

Spring Boot总结(四):提高数据库访问性能

Spring Boot总结(五):安全设计

Spring Boot总结(六):Spring Boot SSO

Spring Boot总结(七):使用分布式文件系统

Spring Boot总结(八):云应用开发

Spring Boot总结(九):构建高性能的服务平台

Spring Boot总结(十):自动配置实现原理

Spring Boot总结(十一):数据访问实现原理

Spring Boot总结(十二):微服务核心技术实现原理

使用Spring Cloud开发的微服务,其独立而有相对隔离的特性,与Docker的理念有异曲同工之妙,所以使用Docker来发布微服务,能够发挥其更大的优势,并且可以非常轻易的构建一个高性能和高可用的服务平台;

Docker是一个开源的应用容器引擎,可以为应用系统创建一个可移植的独立自主的容器。容器运行在Linux的操作系统上,相当于一个虚拟机,但是Docker相比于虚拟机具有非常明显的优势,它不仅启动很快,而且占用资源很少,所以非常适合用来发布微服务。Docker将是未来用来发布服务的重要工具,许多云服务提供商已经提供了对Docker的全力支持;

如果想要将应用发布在Docker上,首先需要在Docker中创建应用的镜像,然后就可以使用Docker命令来运行应用。

9.1 使用Docker

使用Docker可以很方便的创建和管理镜像,以及管理已经生成的和正在运行的容器;

【镜像】

镜像是一种文件存储方式,可以把许多文件做成一个镜像,例如一个操作系统做成GHOST镜像,用来重装操作系统,把一个光盘文件做成一个ISO镜像,等等。

【容器】

容器是镜像运行的一个实例,运行一个镜像,就会生成一个容器。容器生成之后,就可以在容器中管理应用系统了;

Docker 是一个开源工具,它可以让创建和管理 Linux 容器变得简单。容器就像是轻量级的虚拟机,并且可以以毫秒级的速度来启动或停止。Docker 帮助系统管理员和程序员在容器中开发应用程序,并且可以扩展到成千上万的节点。

容器和 VM(虚拟机)的主要区别是,容器提供了基于进程的隔离,而虚拟机提供了资源的完全隔离。虚拟机可能需要一分钟来启动,而容器只需要一秒钟或更短。容器使用宿主操作系统的内核,而虚拟机使用独立的内核。

Docker 的局限性之一是,它只能用在 64 的操作系统上。

1. Docker安装

在Linux上安装Docker要求64位系统,并且内核版本在3.10以上。如果使用CentOS,则使用CentOS 7.0可以符合要求;

【查看Linux的内核版本】

#uname -r

编写如下内容到docker.repo中,以方便yum能够找到Docker引擎:

http://blog.csdn.net/yuan_cheerleaders/article/details/51480077

【启动Docker】

# service docker start

【查看Docker版本信息】

# docker -v

2. Docker常用命令

Docker启动之后,就可以使用Docker来创建和管理镜像了,下列指令可以测试运行一个已经存在的镜像,它将会生成一个容器并且启动它,然后执行java -version指令,最后停止运行的容器;

# docker run --name java8 -it java:8 java  -version

运行上面的指令将启动一个包含Java:8镜像的容器,如果本地没有这个Java:8镜像,将会从远程的镜像服务器中下载一个符合版本号的镜像,执行Java的执行打印其信息,然后退出容器。

现在在系统中,存在一个命令为Java8的镜像和一个处于停止状态的容器。可以使用Docker的一些指令来管理镜像和容器。

  1. docker pull [name]            获取镜像(相当于下载)
  2. docker images                  显示Docker镜像列表
  3. docker inspect [镜像ID]          获取镜像的详细信息
  4. docker search [关键词]            查找关键词镜像列表
  5. docker ps -a                       查看Docker后台进程
  6. docker rmi [镜像标签/镜像ID]                删除镜像
  7. docker cp [file] [容器ID]:/etc/                  复制文件到容器指定位置
  8. docker rm [容器ID]                                     删除容器
  9. docker commit -m "description..." -a "author" [容器ID] [New id]基于已有容器创建新的镜像
  10. docker run -it ubuntu /bin/bash                使用镜像创建一个容器,并在其中运行bash应用(-t 分配一个伪终端,-i 让容器标准输入保持打开)
  11. docker create -it [镜像]            新建一个容器
  12. docker start [容器ID]               运行处于终止状态的容器
  13. docker run -d ubuntu [命令]             后台运行容器
  14. docker logs [容器ID]                          查看容器输出信息
  15. docker stop [-t|--time[=10]] [容器ID]              终止容器,默认等待10s
  16. docker kill [容器ID]                                               直接强制终止容器
  17. docker ps -a(查看所有容器,包括已经停止运行的) -q                                                                 查看处于终止状态的容器
  18. docker restart [容器ID]                                       重启一个容器
  19. docker exec -ti [容器ID] /bin/bash          进入到创建容器中运行交互命令
  20. docker save -o name.tar ubuntu:14.04            存出镜像到本地为name.tar
  21. docker load --input name.tar                              导入镜像存储文件到本地镜像库
  22. docker export [容器ID] > name.tar                  导出停止或运行中的容器到文件中去
  23. cat name.tar | sudo docker import - test/ubuntu:v1.0            导入容器导出的文件成为镜像

3. 使用Docker发布服务

首先执行如下命令停掉CentOS 的防火墙:

#systemctl stop firewalld.service   停止firewall

#systemctl disable firewalld.service   禁止firewall开机启动

首先将各个模块的配置文件中有localhost的改为安装了Docker服务的Linux服务器的IP地址

将整个工程打包,mvn clean package

打包完成之后,可以将jar文件和各个模块中创建镜像的脚本Dockerfile上传到安装有Docker服务的Linux服务器上。可以在Linux服务器上为各个模块创建一个目录,分别存放各个模块的jar和Dockerfile文件;

Docker是创建镜像的一个脚本文件,脚本首先导入java:8的镜像,最后使用Java来运行jar

切换到Dockerfile所在目录,使用#docker build -t xx . 来创建镜像;

使用#docker images可以查看已经创建和存在的镜像;

【运行镜像】

该指令设定服务在后台运行,并将容器的内部端口8888映射到外部端口8888,容器的名字改为config

#docker run --name config -d -p 8888:8888 config

只有在第一次运行服务的时候,才需要使用上面的指令,因为它同时会生成一个容器,所以以后需要运行服务的时候,只要直接启动容器即可;

【查看正在运行的容器】

#docker ps

【查看正在运行的容器中服务的运行情况】

例如:查看config容器的输出日志

#docker logs -f config

【停止容器】

#docker stop 容器名称

【启动容器】

#docker start config

对各个模块都单独容器来进行上面类似的操作;

9.2 创建和管理一个高性能的服务体系

使用Docker发布服务之后,可以使用其他的一些服务管理工具来构建高性能和高可用的服务平台。上面创建的镜像可以很方便的使用docker-compose来管理;

docker-compose工具是一个Docker容器管理工具集,可以很方便的用来创建和重建容器,执行启动和停止容器等管理操作,以及查看整个服务体系的运行情况和输出日志等。

 

使用docker-compose工具,只需要一条指令就能够启动整个分布式服务体系;

1. 安装docker-compose

首先,安装docker-compose工具,使用下列指令下载已经编译的docker-compose:

该指令将会下载docker-compose可执行文件,并保存在/usr/local/bin中

 

curl -L https://github.com/docker/compose/releases/download/1.1.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose

赋予任何用户可执行权限:

chmod +x /usr/local/bin/docker-compose

【查看版本号是否安装成功】

# docker -compose --version

2. docker-compose常用指令

  • build(构建yml中某个服务的镜像) 
    如上,web这个服务是依赖于镜像build的。在本地 也存在Dockerfile文件。 
    可以使用docker-compose build来构建服务的镜像。
  • ps(查看已经启动的服务状态)
  • kill(停止某个服务)
  • logs(可以查看某个服务的log)
  • port(打印绑定的public port)
  • pull(pull服务镜像)
  • up(启动yml定义的所有服务)
  • stop(停止yml中定义的所有服务)
  • start(启动被停止的yml中的所有服务)
  • kill(强行停止yml中定义的所有服务)
  • rm(删除yml中定义的所有服务)
  • restart(重启yml中定义的所有服务)
  • scale(扩展某个服务的个数,可以向上或向下)
  • migrate-to-labels(这个没有实际尝试。根据介绍是将服务从1.2迁移到1.3带labels的版本。docker之前不支持label)
  • version(查看compose的版本)

3. 使用docker-compose管理服务

使用docker-compose.yml配置将一些高可用的微服务,通过links连接成为一个整体,这样就可以通过docker-compose统一管理,并且可以在运行的过程中,动态设定服务的负载均衡实例,从而建立一个高性能的服务平台:

容器名

         image:  指定镜像名称

         ports:  设定容器的内部和外部端口

         links:用来指定一个服务需要依赖的其他服务列表

【在docker-compose.yml文件所在位置,执行如下的命令】

创建如模板所设置的容器,一个一个地创建镜像的容器,然后启动相应的服务

#docker-compose up

上面指令只有未创建容器,即第一次运行的时候,才需要这样执行。当从控制台中退出的时候,会同时停止已经启动的服务,除非上面指令加上了-d参数。生成容器之后,就可以使用如下的指令来启动整个服务体系;

#docker-compose start

在服务运行过程中,如果启动脚本中未设定服务的外部窗口,如服务data,可以使用如下的命令指定服务的个数,这个指令将会在线增加一个容器,并将其自动纳入负载均衡管理中。

#docker -compose scale data=2

【负载均衡】

负载均衡是Spring Cloud 工具集中一个组件Ribbon的功能,这是一个内置了可拔插、可定制的负载均衡组件,它主要具备如下复杂均衡规则:

  1. 简单轮询规则
  2. 加权时间响应规则;
  3. 区域感知轮询规则;
  4. 随机规则;

Spring Cloud默认启用Ribbon的负载均衡功能,也可以在工程的配置中增加如下配置,明确自定启用Ribbon的功能;

ribbon:

         eureka:

                   enabled:true

使用docker-compose,很容易的创建一个高可用和高性能的服务平台,它不但容易管理,而且服务启动速度很快,更加难能可贵的是,它能够动态调整负载均衡配置,实现服务的在线可拔插功能,并且具有自我修复故障的能力。当然,这些功能和性能优势与Spring Cloud的支持是分不开的;

 

图:微服务高可用服务体系结构图

9.3 使用Docker的其他负载均衡实施方法

Docker还可以和其他工具配合使用,配置各种负载均衡服务,搭建高性能的服务平台,例如Docker跟Nginx、Haproxy、Kubernetes等工具配合使用,都能设计出高性能和高可用的负载均衡服务。

1. 使用Nginx与Docker构建负载均衡服务

最简单的莫过于使用Nginx来作为负载均衡服务,连接分布于不同机器上的由Docker发布的服务。如下代码是一个非常简单的Nginx负载均衡配置:

server{

         listene 80;

         server_name 192.168.1.10;

         location  /{

                   proxy_pass  http://blance;

}

}

upstream balance{

         server 192.168.1.11;

         server 192.168.1.12;

}

这个简单的配置是将Nginx安装在一台机器上,对外提供服务,它使用负载均衡的机制,将实际使用的服务分布于其他两台机器上。

2. 阿里云的负载均衡设计实例

在阿里云的负载均衡设计中,使用Nginx和Docker配置的一个可以动态扩容的负载均衡的样例,这也许能够给我们一些参考和启示;

如下代码使用docker-compose的模板,配置了两个Nginx和两个Tomcat,并且每个Tomcat都运行两个容器。

 

nginx:

         image:’nginx:lastest’

         labels:

                   aliyun.routing.port_80:’http://ngtomcat’

                   aliyun.scale:’2’

资料参考:

https://yq.aliyun.com/articles/6816#3

9.4 小结

使用Docker的运行速度非常流畅,这是虚拟机无法比拟的。

使用Docker来发布和管理服务将是未来的发展趋势,此外,Docker还可以跟其他的复杂均衡工具配合使用,以搭建一个高性能和高可用的服务平台。