Docker之路(三)docker安装nginx实现对springboot项目的负载均衡

Docker之路(三)docker+nginx+springboot负载均衡

  • 前言:
  • 一、安装docker
  • 二、安装nginx
  • 三、准备好我们的springboot项目
  • 四、将springboot项目分别build成docker镜像
  • 五、配置nginx并且启动
  • 六、nginx的负载均衡策略
  • 七、nginx的常用属性
  • 八、总结

前言:

本文采用比较经典的方式来集成,如果想了解docker-compse方式的,请移步我的下篇文章。

一、安装docker

请参考我的这篇文章:Docker之路(一)–安装Docker

二、安装nginx

docker pull nginx

这个等同于docker pull nginx:latest,都是拉取最新的镜像版本。这里我们先不着急启动nginx,先把准备好的三个springboot项目准备好。

三、准备好我们的springboot项目

这里我用了同一个springboot项目,然后分了三个端口来打包,端口分别是8181,8182,8183,测试接口也是用的默认的,现在创建一个最新的springboot项目,会自动生成一个BaseController测试类。这里我们就用它这个默认的接口:/hello

@Controller
public class BasicController {
    // http://127.0.0.1:8181/hello?name=lisi
    @RequestMapping("/hello")
    @ResponseBody
    public String hello(@RequestParam(name = "name", defaultValue = "unknown user") String name) {
        return "Hello " + name;
    }
}

然后,我们分别将这个接口的返回值改一下,根据端口一一对应,这样后面nginx负载均衡的时候,我们就容易判断是否成功,具体负载到哪一个端口去了。

  • 8181–> return "Hello " + name;
  • 8182–> return “Hello 2” + name;
  • 8183–> return “Hello 3” + name;

四、将springboot项目分别build成docker镜像

  1. 修改项目为三个不同的端口分别打包,然后上传的linux,目录如下:

    	drwxr-xr-x. 2 root root       54 529 10:36 config
    	-rw-r--r--. 1 root root      133 529 10:36 Dockerfile
    	-rw-r--r--. 1 root root     7172 65 2024 jenkinsTest8182.jar
    	-rw-r--r--. 1 root root     7172 65 2024 jenkinsTest8183.jar
    	-rw-r--r--. 1 root root     7145 57 17:11 jenkinsTest.jar
    	drwxr-xr-x. 2 root root     4096 57 16:49 lib
    
  2. 我这里用的是maven-jar-plugin而不是springboot的maven打包插件,所以目录会有所不同,springboot的会整体打包,没有lib和config这个,这里按照你自己需要来就行。如何将jar包build成docker镜像,参考我这篇文章:Docker之路(二)–用Docker部署一个Web项目。
    在本篇文章,我的Dockerfile是这样写的:如果你是springboot的打包插件,那么就只需要copy jar包为app.jar就行,不需要copy lib和config这个目录文件。

    FROM openjdk:11
    VOLUME /tmp
    #这一步需要修改jenkinsTest.jar为三个不同的jar包名称
    COPY jenkinsTest.jar app.jar
    #这里每次build我都会修改config下application.properties里面的端口
    COPY config config
    COPY lib lib
    ENTRYPOINT ["java","-jar","/app.jar"]
    
  3. build成功后看看我们的镜像:

    [root@localhost docker-nginx]# docker images
    REPOSITORY         TAG       IMAGE ID       CREATED          SIZE
    8183demo           latest    483ecd3a7fff   49 minutes ago   714MB
    8182demo           latest    c1fe57a09bc0   49 minutes ago   714MB
    8181demo           latest    3b76435d0f75   31 hours ago     714MB
    
  4. 运行这三个项目的镜像

    docker run --name 8181demo -d -p 8181:8181 8181demo
    docker run --name 8182demo -d -p 8182:8182 8182demo
    docker run --name 8183demo -d -p 8183:8183 8183demo
    

    然后看看浏览器能否访问
    在这里插入图片描述
    这里是看到是OK了的,然后就可以操作我们的nginx了。

五、配置nginx并且启动

  1. 启动前,需要将nginx的配置挂载一份到宿主机上,这样方便我们修改,而不用每次都进入容器去修改,因为容器里面vim这些指令是没有的。挂载的参数是-v(简易版)或者-mount(复杂版),这两个参数都可已实现挂载,我们后面再讨论,这里使用的是-v。

  2. -v格式: -v [宿主机绝对路径]:[容器路径],
    (1)这里我们在宿主机新建目录/home/docker-nginx,然后在将nginx默认的配置文件:nginx.conf和default.conf复制一份到/home/docker-nginx下面(这个目录最好新建,虽然可以自动生成,但是有时候会出麻烦,还有这两个文件,一定不能是空文件,不是你nginx容器启动不起来)。
    (2)从容器中copy文件:docker cp [容器名字或者id]:容器路径 宿主机路径

      docker cp mynginx:/etc/nginx/nginx.conf /home/docker-nginx/nginx.conf
      docker cp mynginx:/etc/nginx/conf.d/default.conf /home/docker-nginx/default.conf
    

    注意,这里容器启动才能copy,所以要不你先不挂载启动一个容器copy,要不就去搜一下默认的文件是啥(文章后面我会贴出来)。

  3. ngnix完整的启动命令:挂载两个conf文件和一个log日志目录,然后映射ngnix端口为:30001

    docker run --name mynginx \
    -v /home/docker-nginx/nginx.conf:/etc/nginx/nginx.conf \
    -v /home/docker-nginx/log:/var/log/nginx \
    -v /home/docker-nginx/default.conf:/etc/nginx/conf.d/default.conf \
    -d -p 30001:80 nginx
    
  4. 访问nginx看是否成功
    在这里插入图片描述

  5. 修改nginx配置文件。
    这里有两个文件,一个是nginx.conf和default.conf,这两者的关系是:nginx.conf包含了default.conf,这个很关键。
    (1)修改nginx.conf:因为我们用的是三个项目的集群,这里我们先将集群配置加到nginx.conf里面,使用upstream标签,后面名字随便取,我这里是demo1。上面都有注释

    user  nginx;
    worker_processes  auto;
    
    error_log  /var/log/nginx/error.log notice;
    pid        /var/run/nginx.pid;
    
    events {
        worker_connections  1024;
    }
    
    http {
        include       /etc/nginx/mime.types;
        default_type  application/octet-stream;
    
        log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                          '$status $body_bytes_sent "$http_referer" '
                          '"$http_user_agent" "$http_x_forwarded_for"';
    
        access_log  /var/log/nginx/access.log  main;
    
        sendfile        on;
        #tcp_nopush     on;
    
        keepalive_timeout  65;
    
        #gzip  on;
    	#nginx默认配置文件,本文本案例只添加了如下配置
       upstream demo1 {
            server 172.16.72.128:8181;
            server 172.16.72.128:8182;
            server 172.16.72.128:8183;
       }
    	#这行就是上面所说的,这两个文件的包含关系,在这里引用
        include /etc/nginx/conf.d/*.conf;
    }
    
    

    (2)修改default.conf,将我们定义的upstream demo1添加进location 标签里面去。

    server {
        listen       80;
        listen  [::]:80;
        server_name  localhost;
        #access_log  /var/log/nginx/host.access.log  main;
    
        location / {
        #这行就是我们作的唯一修改
    	proxy_pass http://demo1;
           # root   /usr/share/nginx/html;
           # index  index.html index.htm;
        }
    
        #error_page  404              /404.html;
    
        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   /usr/share/nginx/html;
        }
    
        # proxy the PHP scripts to Apache listening on 127.0.0.1:80
        #
        #location ~ \.php$ {
        #    proxy_pass   http://127.0.0.1;
        #}
    
        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        #location ~ \.php$ {
        #    root           html;
        #    fastcgi_pass   127.0.0.1:9000;
        #    fastcgi_index  index.php;
        #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
        #    include        fastcgi_params;
        #}
    
        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        #location ~ /\.ht {
        #    deny  all;
        #}
    
    }
    
    

    负载均衡策略:我们什么都没有配置,用的是nginx默认的轮询策略,关于这点,我们会在后面详细讲解。

  6. 重启nginx容器查看是否实现了负载均衡

    docker container restart mynginx
    

    浏览器访问同一个URL,看看是否会负载均衡
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    这里可以看到,我请求了三次,分别返回了三个结果,然后再请求又从第一个返回,证明了我们的轮询策略是成功了的。

六、nginx的负载均衡策略

以下配置均采用本文的集群案例,介绍三种常用的。

  1. 轮询策略
    默认的策略,不需要额外配置,本文就使用默认的配置。
  2. 权重策略
    可以为某些服务器添加权重,让该服务器更多的为用户提供服务,后面添加weight字段就行。
    upstream demo1 {
        server 172.16.72.128:8181 weight=6;
        server 172.16.72.128:8182 weight=3;
        server 172.16.72.128:8183 weight=1;
    }
    
  3. IPHASH策略
    同一个ip一只访问同一个服务器,缺点就是服务器炸了就没法分发请求。
    upstream demo1 {
    	ip_hash;
        server 172.16.72.128:8181 weight=6;
        server 172.16.72.128:8182 weight=3;
        server 172.16.72.128:8183 weight=1;
    }
    

七、nginx的常用属性

  1. down属性,标记不可用,这样就不会像这个服务器分发请求。
	upstream demo1 {
	    server 172.16.72.128:8181 down;
	    server 172.16.72.128:8182;
	    server 172.16.72.128:8183;
	}
  1. BACKUP 备用机设置,正常情况下该服务器不会被访问.当主机全部宕机或者主机遇忙时,该服务器才会访问.
	upstream demo1 {
	    server 172.16.72.128:8181 down;
	    server 172.16.72.128:8182 backup;
	    server 172.16.72.128:8183;
	}
  1. 宕机服务器高可用实现
    当服务器宕机时,如果访问的失败达到最大失败次数,则自动标识为down,在一定的周期之内,如果服务器恢复正常,则还会尝试访问故障机。
    max_fails=10 最大的失败次数
    fail_timeout=60s; 设定周期为60秒
	upstream demo1 {
	    server 172.16.72.128:8181 max_fails=10 fail_timeout=60s;
	    server 172.16.72.128:8182 max_fails=10 fail_timeout=60s;
	    server 172.16.72.128:8183 max_fails=10 fail_timeout=60s;
	}

八、总结

以上就是本次文章全部内容了,都是比较简单和基础的操作,但是一些细节没注意还是容易出现问题,欢迎评论区讨论和错误纠正,我们Docker之路第四期见。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/683702.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

第二证券:A股重磅调整!富时中国A50指数将纳入中远海控中国中车

重要的音讯有哪些 A股,重磅调整! 6月5日,富时罗素宣布对富时我国50指数、富时我国A50指数、富时我国A150指数、富时我国A200指数、富时我国A400指数的季度审阅变更。该变更将于2024年6月21日星期五收盘后(即2024年6月24日星期一…

使用HTML、CSS和JavaScript编写一个注册界面(一)

倘若文章或代码中有任何错误或疑惑&#xff0c;欢迎提出交流哦~ HTML和CSS 首先&#xff0c;我们需要编写一个简洁的注册界面。 简单编写下&#xff0c;如下&#xff1a; 呈现效果为&#xff1a; <!DOCTYPE html> <html lang"en"><head><me…

Python 全栈体系【四阶】(五十七)

第五章 深度学习 十三、自然语言处理&#xff08;NLP&#xff09; 2. 传统NLP处理技术 2.4 关键词提取 关键词提取是提取出代表文章重要内容的一组词&#xff0c;对文本聚类、分类、自动摘要起到重要作用。此外&#xff0c;关键词提取还能使人们便捷地浏览和获取信息。现实…

哪款开放式耳机佩戴最舒服?2024五款备受推崇产品分享!

​作为一位耳机领域的资深数码评测师&#xff0c;我极力推荐开放式耳机作为日常佩戴之选。这款耳机凭借其创新的非入耳设计&#xff0c;有效避免了传统入耳式耳机长时间佩戴导致的耳道不适和感染风险&#xff0c;同时提供了稳固舒适的佩戴体验&#xff0c;特别适合运动爱好者如…

转让北京防水防腐保温工程施工二级资质流程和要求

防水资质全称叫作防水防腐保温专业承包二级资质&#xff0c;办理的条件和要求相对于其他专业的资质门槛比较低&#xff0c;如果条件允许建议企业直接新办&#xff0c;因为转让还是有一定风险存在&#xff0c;防水二级资质转让的费用取决于多个因素&#xff0c;如地区、市场需求…

MySQL的增删改查2

文章目录 1. 数据库约束1.1 约束类型1.2 NOT NULL约束1.3 UNIQUE唯一约束1.4 DEFAULT默认值约束1.5 PRIMARY KEY主键约束1.6 FOREIGN KEY外键约束1.7 CHECK约束 2. 新增3. 查询3.1 聚合查询3.1.1 聚合函数3.1.2 GROUP BY子句3.1.3 HAVING 3.2 联合查询3.2.1 内连接3.2.2 外连接…

趣测小程序开发搭建,趣测趣玩小程序是何物?

一、趣测小程序简介 趣测趣玩小程序是一款提供趣味测试和玩乐功能的应用程序。用户可以通过该小程序参与各种有趣的测试&#xff0c;这些测试可能涵盖性格、情感、智力等多个方面&#xff0c;旨在为用户提供轻松愉快的体验。同时&#xff0c;该小程序还可能包含一些游戏元素&a…

【qt】项目移植

项目移植 一.前言二.同名问题三.具体操作1.修改文件名2.修改类名3.修改一些不能自动改的名4.修改.ui文件5.删除原来自动生成的ui_xxx.h文件6.修改头文件 四.导入项目五.使用导入的项目六.项目建议 一.前言 终于概率论考完了,有时间了,接着上个项目,我们继续来完成我们的多窗口开…

谷云科技陆才慧:不是零ETL,而是零代码ETL丨数据猿专访

大数据产业创新服务媒体 ——聚焦数据 改变商业 数据集成&#xff0c;是将来自多个来源的数据整合到一个统一的平台&#xff0c;以实现集中管理和分析。它通过消除数据孤岛、提高数据质量&#xff0c;支持实时决策、增强数据分析能力。因此&#xff0c;数据集成在数据生命周期…

Qt CAN总线发送和接收案例

文章目录 设置比特率类设置比特率类实现 发送数据帧类发送数据帧类的实现m_ui 发送帧界面 连接类连接类实现连接类UI设计 主窗口类主窗口类实现主界面UI 整体UIQT案例 设置比特率类 // 文件: BitRateBox.h // 作用: 定义了一个用于选择比特率的组合框类 BitRateBox&#xff0c…

HR在线人才测评,如何判断候选人的学习能力?

在选拔人才的过程中&#xff0c;学习能力突出的候选人&#xff0c;能以非常快的速度适应工作环境&#xff0c;并且会在工作当中制定清晰的学习规划&#xff0c;不断的提升自己&#xff0c;不断的彰显个人在企业当中的价值&#xff0c;助力企业的长远发展。 只有选拔进来的人才…

【原创】springboot+mysql村务档案管理系统设计与实现

个人主页&#xff1a;程序猿小小杨 个人简介&#xff1a;从事开发多年&#xff0c;Java、Php、Python、前端开发均有涉猎 博客内容&#xff1a;Java项目实战、项目演示、技术分享 文末有作者名片&#xff0c;希望和大家一起共同进步&#xff0c;你只管努力&#xff0c;剩下的交…

【C#】多线程中,跨线程实现对UI控件更新

问题描述&#xff1a; “Cross-thread operation not valid :Control ‘listBox1’ accessed from a thread other than the thread it was created on” &#xff0c;即“线程间操作无效&#xff0c;从不是创建控件“listbox1”的线程访问它。” 原因分析&#xff1a; UI控件…

零售行业运营有哪些业务场景?详解各业务场景的分析指标和维度

在当今这个数字化迅速发展的时代&#xff0c;零售行业正经历着前所未有的变革。传统的零售模式正在被新兴的技术和创新的业务场景所颠覆&#xff0c;消费者的需求和购物习惯也在不断地演变。零售行业的运营&#xff0c;作为连接消费者、产品和市场的关键环节&#xff0c;对于零…

06Docker-Compose和微服务部署

Docker-Compose 概述 Docker Compose通过一个单独的docker-compose.yml模板文件来定义一组相关联的应用容器&#xff0c;帮助我们实现多个相互关联的Docker容器的快速部署 一般一个docker-compose.yml对应完整的项目,项目中的服务和中间件对应不同的容器 Compose文件实质就…

【CMake系列】05-静态库与动态库编译

在各种项目类型中&#xff0c;可能我们的项目就是一个 库 项目&#xff0c;向其他人提供 我们开发好的 库 (windows下的 dll /lib &#xff1b; linux下的 .a / .so)&#xff1b;有时候在一个项目中&#xff0c;我们对部分功能 打包成 库&#xff0c;方便在不同地方进行调用 静…

idea 常用插件推荐

文章目录 1、Lombok2、Convert YAML and Properties File3、Grep Console4、MyBatisX5、Free MyBatis Tool6、MyBatis Log EasyPlus &#xff08;SQL拼接&#xff09;7、MyBatisPlus8、Eclipse theme9、Eclipse Plus Theme10、Rainbow Brackets Lite - Free and OpenSource&…

MongoDB CRUD操作:地理位置应用——通过地理空间查询查找餐厅

MongoDB CRUD操作&#xff1a;地理位置应用——通过地理空间查询查找餐厅 文章目录 MongoDB CRUD操作&#xff1a;地理位置应用——通过地理空间查询查找餐厅地图的扭曲搜索餐厅浏览数据查找当前邻居查找附近所有餐厅查找一定距离内的餐厅使用$geoWithin&#xff0c;不排序使用…

上位机图像处理和嵌入式模块部署(f407 mcu中tf卡模拟u盘)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 在f407开发板上面&#xff0c;本身是有一个usb接口的。这个usb接口也不仅仅是作为电源使用的&#xff0c;它还可以用来做很多的事情。一方面&#…

学Python,看一篇就够

学Python&#xff0c;看一篇就够 python基础注释变量标识符命名规则使用变量认识bugDebug工具打断点 数据类型输出转义字符输入输入语法输入的特点 转换数据类型pycharm交互运算符的分类赋值运算符复合赋值运算符比较运算符逻辑运算符拓展 条件语句单分支语法多分支语法拓展 if…