docker搭建nginx负载均衡

news2024/11/25 2:28:14

一点小背景

docker起了几个服务,没有配置端口映射,导致不能通过网络访问。当然,更简单的方式是加端口映射,笔者的情况更复杂一些,就想到了用nginx映射一下。

Nginx(发音同“engine X”)是异步框架的网页服务器,也可以用作反向代理、负载平衡器和HTTP缓存。

—— https://zh.wikipedia.org/wiki/Nginx

第一个demo

最简单启动

docker run -itd --name tnginx -p 10010:80 nginx

访问一下

wtnginx

静态网页

nginx默认读取/usr/share/nginx/html下面的静态文件

创建1个存放静态文件的文件夹映射给容器

mkdir html

echo "<h1>Hello Nginx!</h1>" > ./html/index.html		# 创建1个静态页面

# docker rm -f tnginx		# 删掉之前存在的,否则会冲突
docker run -itd --name tnginx -p 10010:80 -v "$PWD/html":/usr/share/nginx/html nginx

映射物理机文件的好处在于即使容器停止或者被清理,再次启动映射相同的文件还能恢复到同一状态。修改物理机文件也会在容器内生效。后续的配置修改只需要修改物理机上的配置文件,然后重启nginx容器即可docker restart tnginx

再访问一下

hnginx

配置文件

默认读/etc/nginx/文件夹下的nginx配置文件,咱也不知道长什么样,从docker容器中捞一个出来

docker cp tnginx:/etc/nginx ./

用的是nginx/nginx.conf配置文件

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;

    include /etc/nginx/conf.d/*.conf;
}

改一下静态文件的目录地址,在配置文件里http配置中添加以下配置

http {
    ...
    server {
    	listen 80 default_server;
    	root /www/html;
    	index index.html;
    }
}

映射配置文件和静态文件的目录

# docker rm -f tnginx		# 删掉之前存在的,否则会冲突
docker run -itd --name tnginx -p 10010:80 -v "$PWD/html":/www/html -v "$PWD/nginx":/etc/nginx nginx

再访问一下http://192.168.9.109:10010/仍然是work的

测试服务

为了直观体现下文操作的效果,用python简单起个http服务,不感兴趣可跳过~

# service.py
from flask import Flask, request
import multiprocessing
from multiprocessing import Process

multiprocessing.set_start_method("fork")  # 防止Process的pickle报错

class MyFlask(Flask):
    def getResponse(self):
        return "{}_{}> {}".format(self.name, multiprocessing.current_process().name, request.base_url), \
               200, {'Access-Control-Allow-Origin': '*'}    # 最后的header避免fetch访问时跨域报错

app1 = MyFlask('service_1')

@app1.route('/hello')
@app1.route('/user/add')
@app1.route('/user/get')
def service1_handler():
    return app1.getResponse()

app2 = MyFlask('service_2')

@app2.route('/book/add')
@app2.route('/book/get')
def service2_handler():
    return app2.getResponse()

if __name__ == '__main__':
    Process(target=app1.run, args=('0.0.0.0', 10001)).start()
    Process(target=app1.run, args=('0.0.0.0', 10002)).start()
    Process(target=app2.run, args=('0.0.0.0', 20001)).start()

Process-1、Process-2启动了app1,Process-3启动了app2

做了个页面直观一点看看响应

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
  <link rel="stylesheet" href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" integrity="sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu" crossorigin="anonymous">
  <script src="https://cdn.staticfile.org/jquery/2.0.0/jquery.min.js"></script>
</head>
<body>
<form class="form-inline">
  <button type="button" class="btn btn-primary" onclick="visit()">访问</button>
  <select class="form-control" id="s_url">
    <option><span>http://192.168.9.109:10010/hello</span></option>
    <option><span>http://192.168.9.109:10010/user/add</span></option>
    <option><span>http://192.168.9.109:10010/user/get</span></option>
    <option><span>http://192.168.9.109:10010/book/add</span></option>
    <option><span>http://192.168.9.109:10010/book/get</span></option>
  </select>
  <div class="form-group">
    <input type="text" id="num" class="form-control" style="width:50px" value="1">
  </div>
  <span></span>
</form>

<div id="result">
  <div>=================================================</div>
</div>
<script type="text/javascript">
  function visit(){
    var url=$("#s_url option:selected").val();
    var num=$("#num").val();
    for (var i=0;i<num;i++)
    {
        fetch(url)
          .then(function(data) {
              return data.text();
          }).then(function(data) {
              $("#result").append("<div>"+data+"</div>");
        });
    }
  }
</script>
</body>
</html>

效果如下
在这里插入图片描述

路由规则

规则优先更精准的匹配

http {
	...
	server {
    ...
    location / {	# 未被其他配置规则命中的走这里
    	proxy_pass  http://192.168.9.109:10001;		# app1(Process-1)
    }
    location /book {	# /book 开头的走这里
    	proxy_pass  http://192.168.9.109:20001;		# app2(Process-2)
    }
  }
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
/book/add路由到了Process-3上的app2,/user/add路由到了默认去了app1,应为没有配置app2的/hello/hello去访问了app1

负载均衡

不加额外配置是轮询的

http {
	upstream myservice {	# 这里是负载均衡的配置
	    server 192.168.9.109:10001;		# 不加其他配置默认是轮询的
	    server 192.168.9.109:10002;
	}
  
	server {
	    ...
	    location / {
	    	proxy_pass  http://myservice;		# 给server指定proxy到下面的 myservice
	    }
    }
}

在这里插入图片描述

更改配置按权重选择

  upstream myservice {	# 这里是负载均衡的配置
    server 192.168.9.109:10001 weight=4;		# 配置权重
    server 192.168.9.109:10002 weight=1;
  }

weight

其他配置

  upstream myservice {
    server 192.168.9.109:10001 weight=4 max_fails=3 fail_timeout=15;
    server 192.168.9.109:10002 backup;		# 备份,所有不可用才会生效
    server 192.168.9.109:10003 down;		# 标识不可用	
    server 192.168.9.109:10004 max_conns=1000;
  }

其他

设置header

经由nginx转发以后,客户端的信息变成nginx的信息,可以通过设置header把客户端的信息传过去

   location / {
   		...
    	proxy_set_header Host $http_host;		# nginx的ip:port
    	proxy_set_header X-Upstream-Addr $upstream_addr;	# 理应是真实服务的ip:port,但是我这里没生效
    	proxy_set_header X-Real-IP $remote_addr;	# 发起请求的ip
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;	# 发起请求的ip
   }

内置变量

如上使用的$http_host是nginx的内置变量,更多可参见

http://nginx.org/en/docs/http/ngx_http_core_module.html#variables

内置变量还可以在nginx的输出日志中使用,即

http {
    ...

    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;
    ...
}

参考

配置路由的 https://www.cnblogs.com/jackylee92/p/6836948.html

负载均衡的策略 https://www.cnblogs.com/itzgr/p/13330613.html

https://www.ruanyifeng.com/blog/2018/02/nginx-docker.html

upsteam_addr http://nginx.org/en/docs/http/ngx_http_upstream_module.html#variables

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

避免“文献综抄”,5种写作结构助你完成文献综述→

很多作者可能有过这样的体验&#xff1a;读了很多文献&#xff0c;但在写综述的时候总感觉不像是在写文献综述&#xff0c;更像在写文献总结 如果引用方面不注意&#xff0c;甚至会成为文献综抄。 那么&#xff0c;你可以参考下我们整理的以下资料哦~ 01 文献总结和文献综述的…

DCDC反馈电阻的阻值如何取值?

DCDC芯片的反馈电阻 下图为我们公司现在常用的两款DCDC芯片&#xff0c;TPS54335ADDA/TI和LMR14050SDDA/TI。 其中RFBT和RFBB都是反馈电阻&#xff0c;可以通过调节这两个电阻的比值来输出 预期电压。 FBT&#xff1a;feedback top&a…

保姆级丨XAMPP安装使用

0x00 前言 XAMPP 是一个完全免费&#xff0c;易于安装的 Apache 发行版&#xff0c;包含 MariaDB &#xff0c; PHP 和 Perl 。 XAMPP 开源软件包已经设置为非常容易安装和使用。 0x01 环境说明 Windows 11xampp-windows-x64-8.2.4-0-VS16-installer 0x02 准备工作 首先要访问…

数据库分区;pgAdmin操作pgsql分区;修改pgsql数据库名字

目录 分区 什么是分区 分区的优势 pgAdmin操作pgsql分区 创建父表 创建分区 数据入库分区 扩展&#xff08;按天创建分区脚本&#xff09; 修改数据库名字 链接 分区 什么是分区 指将一个大的表或索引分成多个小的、独立的部分&#xff0c;每个部分称为一个分区&#x…

带你了解家居智能的心脏:物联网关

本文将介绍家庭物联网关的相关内容&#xff0c;将明白物联网关在家庭这个场景当中的应用。现在市面上各种各样的智能家居的家电或者其他设备非常多&#xff0c;那么这就需要一个智能的设备去对所有的家电进行管控。这样一个设备就是家庭智能网关&#xff0c;家庭物联网关是家居…

Py之onnx:onnx/onnxruntime库的简介、安装、使用方法之详细攻略

Py之onnx&#xff1a;onnx/onnxruntime库的简介、安装、使用方法之详细攻略 目录 onnx/onnxruntime库的简介 onnx/onnxruntime库的安装 onnx/onnxruntime库的使用方法 1、基础用法 onnx/onnxruntime库的简介 Open Neural Network Exchange&#xff08;ONNX&#xff09;是一…

Python每日一练(20230513) 粉刷房子 I\II\III Paint House

目录 1. 粉刷房子 Paint House 2. 粉刷房子 II Paint House-ii 3. 粉刷房子 III Paint House-iii &#x1f31f; 每日一练刷题专栏 &#x1f31f; Golang每日一练 专栏 Python每日一练 专栏 C/C每日一练 专栏 Java每日一练 专栏 leetcode题号分别为&#xff1a; 256、2…

32 位 ARM® Cortex®-M0+ 单片机,PY32F002B 系列微控制器

PY32F002B 系列微控制器采用高性能的 32 位 ARM Cortex-M0内核&#xff0c;宽电压工作范围的 MCU。嵌入24Kbytes Flash 和 3Kbytes SRAM 存储器&#xff0c;最高工作频率 24MHz。包含多种不同封装类型多款产品。 芯片集成I2C、SPI、USART 等通讯外设&#xff0c;1 路 12bit ADC…

UNIAPP实战项目笔记70 购物车删除商品的前后端交互

UNIAPP实战项目笔记70 购物车删除商品的前后端交互 思路 需要用到vuex 传id值到后端,删除指定id购物车数据 案例截图 购物车商品编辑页面 代码 后端代码 index.js var express require(express); var router express.Router(); var connection require(../db/sql.js); va…

6.Go语言学习笔记-结合chatGPT辅助学习Go语言底层原理

1、Go版本 go1.14.15 2、汇编基础 推荐阅读:GO汇编语言简介 推荐阅读:A Quick Guide to Gos Assembler - The Go Programming Language 精简指令集 数据传输: MOV/LEA 跳转指令: CMP/TEST/JMP/JCC 栈指令: PUSH/POP 函数调用指令: CALL/RET 算术指令: ADD/SUB/MUL/DIV …

PFCdocumentation_FISH Rules and Usage

目录 FISH Scripting FISH Rules and Usage Lines Data Types Reserved Names for Functions and Variables Scope of Variables Functions: Structure, Evaluation, and Calling Scheme Arithmetic: Expressions and Type Conversions Redefining FISH Functions Ex…

hadoop03

MapReduce是Hadoop系统核心组件之一&#xff0c;它是一种可用于大数据并行处理的计算模型、框架和平台&#xff0c;主要解决海量数据的计算&#xff0c;是目前分布式计算模型中应用较为广泛的一种。 练习&#xff1a;计算a.txt文件中每个单词出现的次数 hello world hello ha…

Android View 事件分发机制,看这一篇就够了

在 Android 开发当中&#xff0c;View 的事件分发机制是一块很重要的知识。不仅在开发当中经常需要用到&#xff0c;面试的时候也经常被问到。 如果你在面试的时候&#xff0c;能把这块讲清楚&#xff0c;对于校招生或者实习生来说&#xff0c;算是一块不错的加分项。对于工作…

三种方式在HTML使用阿里字体图标--iconfont阿里巴巴矢量图标库

好久没用到阿里巴巴的图标&#xff0c;突然要用到就发现不会用了&#xff0c;只会导出png格式的图标png了 目录 1、字体图标 方法一、本地使用通过类名使用阿里矢量图标 1、把图标添加入库 2、把图标添加到项目 3、下载字体图标 4、使用文件 5、在对应的HTML页面上引入…

瑞吉外卖项目笔记01——环境搭建、后台登录功能

1.1 数据库 数据库&#xff1a; 创建一个空白数据库reggie&#xff0c;然后导入执行SQL文件创建的表如下&#xff1a; 1.2 项目依赖 项目依赖&#xff1a; pom.xml文件内的依赖 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"…

国外APP项目的上线流程

现在很多创业者希望自己的项目能走出国内&#xff0c;向全球各地发展&#xff0c;尤其对于一些通用APP来说&#xff0c;国外可以增加一个新的收入渠道。比如常见的出海APP有小型游戏、手机清理、杀毒软件等等&#xff0c;这些类型的APP在全球的使用基本都是一样的&#xff0c;因…

Lucene(1):Lucene介绍

Lucene官网&#xff1a; http://lucene.apache.org/ 1 搜索技术理论基础 1.1 lucene优势 原来的方式实现搜索功能&#xff0c;我们的搜索流程如下图&#xff1a; 上图就是原始搜索引擎技术&#xff0c;如果用户比较少而且数据库的数据量比较小&#xff0c;那么这种方式实现搜…

Lucene(2):Lucene全文检索的流程

1 索引和搜索流程图 &#xff08;1&#xff09;绿色表示索引过程&#xff0c;对要搜索的原始内容进行索引构建一个索引库&#xff0c;索引过程包括&#xff1a; 确定原始内容即要搜索的内容 获得文档创建文档分析文档索引文档 &#xff08;2&#xff09;红色表示搜索过程&…

win10安装conda

conda是一个开源的软件包管理系统和环境管理系统&#xff0c;用于安装、管理和升级各种软件和应用程序。它可以在多个操作系统上运行&#xff0c;支持数百种语言和各种计算机程序。conda提供了安装软件包、创建和管理虚拟环境、配置依赖关系等功能&#xff0c;并且可以轻松地在…

Mac+Vscode+PyQt

纵览 1、需要安装Python&#xff0c;而我安装了Anaconda&#xff0c;并建立了一个虚拟环境env_qt2、在Vscode的终端中利用命令&#xff1a;3、在Vscode的扩展中安装「PYQT Integration」插件&#xff0c;4、可以在bin文件夹下创建一个无后缀的文件des&#xff0c;输入&#xff…