准备
一台linux系统,安装docker,nginx
目标
使用SpringBoot创建一个web应用,使用docker一次发布多个应用实例,使用nginx负载均衡,对外提供服务入口
步骤一:构建web应用
使用springBoot构建一个最简单的应用,@RestController对外暴露一个请求地址http://localhost:8080,使用request.getLocalAddr()返回本地ip,用以区分负载均衡的结果。OK,就这么简单一个程序,使用spring-boot-maven-plugin插件配置好mainClass,打包成jar包备用(下文中命名为demo.jar)。
步骤二:构建dockerfile
我们使用Dockerfile方式构建自己的应用镜像,然后运行若干个容器:
1、将jar包上传到linux系统中(当然,以后可以用脚本、jekins等方式来简化上传的方式)
2、下载基础镜像docker pull java:8-jre
,镜像的版本可以去https://hub.docker.com/看,标记[official]的是官方版本
3、创建Dockerfile,内容如下
FROM java:8-jre
VOLUME /tmp
ADD demo.jar /demo.jar
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom", "-jar","/demo.jar"]
注:demo.jar我放在了Dockerfile同一目录下,所以ADD的时候用的是相对路径。
步骤三:使用脚本运行多个web应用
脚本reload.sh
功能:
关闭之前的java_web应用,删除java_web镜像,重新构建java_web镜像,发布若干个应用。
此脚本用于我发布新jar包后,更新web服务。
内容如下:
#停止并删除运行的web应用容器
#注:linux中,grep可按行过滤结果,awk可按列过滤结果,已达到我们想关闭所用java_web容器的目的
docker kill $(docker ps -a|grep java_web |awk '{print $1}')
docker rm $(docker ps -a|grep java_web |awk '{print $1}')
#删除并重构镜像,构建命令不要漏了最后一个点
docker rmi java_web
docker build -t java_web .
#根据命令参数,发布若干个web应用
N=$1
while(($N>0))
do
docker run --name j$N -d -p 900$N:8080 java_web
let N--
done
执行脚本./reload.sh 5
构建5个web应用。
curl localhost:9001
,变换端口9001~9005,可以看到不同的ip返回。
配置nginx.conf实现负载均衡
我们以不同权重的方式实现负载均衡,配置如下:
注:记录一个我遇到的问题,就是upstream后自定义的名字不能有下划线_
否则404,这里我改成了doclist
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
upstream doclist {
server 127.0.0.1:9001 weight=50;
server 127.0.0.1:9002 weight=30;
server 127.0.0.1:9003 weight=10;
server 127.0.0.1:9004 weight=6;
server 127.0.0.1:9005 weight=4;
}
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://doclist;
root html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
最后多次访问curl localhost
(默认80端口)可以看到负载均衡的效果。