HAProxy- https、四层负载实现与 负载均衡关键技术

news/2025/2/26 16:35:02

目录

1、HAProxy实现四层负载

四层负载示例

ACL示例-四层访问控制

HAProxy-%20https%E5%AE%9E%E7%8E%B0-toc" name="tableOfContents" style="margin-left:0px">2、HAProxy- https实现

HAProxy%20https%E5%AE%9E%E7%8E%B0-toc" name="tableOfContents" style="margin-left:40px">HAProxy https实现

证书制作

https配置示例

修改后端服务器的日志格式

验证https

3、 负载均衡关键技术

1、什么是 Session

2、什么是 Session 共享

1、基于 Cookie 的 Session 共事

2、基于数据库的 Session 共享

3、Session 复制

4、基于 Memcache/Redis 的 Session 共享

3、什么是会话保持


HAProxy%E5%AE%9E%E7%8E%B0%E5%9B%9B%E5%B1%82%E8%B4%9F%E8%BD%BD" name="1%E3%80%81HAProxy%E5%AE%9E%E7%8E%B0%E5%9B%9B%E5%B1%82%E8%B4%9F%E8%BD%BD">1、HAProxy实现四层负载

针对有特殊访问写完的应用场景

  • MySQL
  • Redis
  • Memcache
  • RabbitM

四层负载示例

注意:如果使用frontend和backend,一定在frontend和backedn段中都指定mode tcp

listen redis-port
  bind 10.0.0.7:6379
  mode tcp
  balance leastconn
  server server1 10.0.0.17:6379 check
  server server1 10.0.0.27:6379 check backup

范例:对 MySQL 服务实现四层负载

[root@centos7 ~]#vim /etc/haproxy/haproxy.cfg
listen openlab_mysql
  bind 10.0.0.7:3306
  mode tcp
  balance leastconn
  server mysql1 10.0.0.17:3306 check  
  server mysql2 10.0.0.27 check           #不写端口号,可以转发,但无法check状态

#或者使用frontend和backend实现
frontend mysql
      bind :3306
      mode tcp                            #必须指定tcp模式
      default_backend mysqlsrvs
backend mysqlsrvs
      mode tcp                            #必须指定tcp模式
      balance leastconn
      server mysql1 10.0.0.17:3306
      server mysql2 10.0.0.27:3306

[root@centos7 ~]#systemctl restart haproxy

#在后端服务器安装和配置mariadb服务
[root@centos7 ~]#yum -y install mariadb-server
[root@centos7 ~]#mysql -e "grant all on *.* to test@'10.0.0.%' identified by
'123456'"
[root@centos7 ~]#vim /etc/my.cnf
[mysqld]
server-id=17 #在另一台主机为27
[root@centos7 ~]#systemctl start mariadb

#测试
[root@centos6 ~]#mysql -utest -p123456 -e "show variables like 'hostname'"
+---------------+--------------------------+
| Variable_name | Value                   |
+---------------+--------------------------+
| hostname     | centos17.wangxiaochu.com |
+---------------+--------------------------+
[root@centos6 ~]#mysql -utest -p123456 -e "show variables like 'hostname'"
+---------------+--------------------------+
| Variable_name | Value                   |
+---------------+--------------------------+
| hostname     | centos27.wangxiaochu.com |
+---------------+--------------------------+

[root@centos6 ~]#mysql -utest -p123456 -h10.0.0.7 -e 'select @@server_id'
+-------------+
| @@server_id |
+-------------+
|          17 |
+-------------+
[root@centos6 ~]#mysql -utest -p123456 -h10.0.0.7 -e 'select @@server_id'
+-------------+
| @@server_id |
+-------------+
|          27 |
+-------------+

ACL示例-四层访问控制

frontend web_host
    bind 10.0.0.7:80
    mode http
    balance roundrobin
    log global
    option httplog
###################### acl setting ###############################  
    acl static_path path_beg  -i /static /images /javascript
    acl invalid_src src 192.168.1.0/24 10.0.0.8
###################### acl hosts #################################
    use_backend static_path_host if HTTP_1.1 TRUE static_path
    tcp-request connection reject if invalid_src     #四层ACL控制  
    default_backend default_web
################### backend hosts ################################
backend php_server_host
    mode http
    server web1 10.0.0.17 check inter 2000 fall 3 rise 5

backend static_path_host
    mode http
    server web1 10.0.0.27 check inter 2000 fall 3 rise 5

backend default_web
    mode http
    server web1 10.0.0.37:80 check inter 2000 fall 3 rise 5

HAProxy-%20https%E5%AE%9E%E7%8E%B0" name="2%E3%80%81HAProxy-%20https%E5%AE%9E%E7%8E%B0">2、HAProxy- https实现

HAProxy%20https%E5%AE%9E%E7%8E%B0" name="HAProxy%20https%E5%AE%9E%E7%8E%B0">HAProxy https实现

#配置HAProxy支持https协议,支持ssl会话;
  bind *:443 ssl crt /PATH/TO/SOME_PEM_FILE  

#crt 后证书文件为PEM格式,且同时包含证书和所有私钥  
       cat demo.crt demo.key > demo.pem

#把80端口的请求重向定443
  bind *:80
  redirect scheme https if !{ ssl_fc }    

#向后端传递用户请求的协议和端口(frontend或backend)
  http_request set-header X-Forwarded-Port %[dst_port]
  http_request add-header X-Forwared-Proto https if { ssl_fc }

证书制作

#方法1
[root@centos7 ~]mkdir /etc/haproxy/certs/
[root@centos7 ~]cd /etc/haproxy/certs/
[root@centos7 certs]#openssl genrsa -out haproxy.key 2048
[root@centos7 certs]#openssl req -new -x509 -key haproxy.key -out haproxy.crt
-subj "/CN=www.openlab.org"
#或者用下一条命令实现
[root@centos7 certs]#openssl req -x509 -newkey rsa:2048 -subj
"/CN=www.openlab.org" -keyout haproxy.key -nodes -days 365 -out haproxy.crt

[root@centos7 certs]#cat haproxy.key haproxy.crt > haproxy.pem
[root@centos7 certs]#openssl x509 -in haproxy.pem -noout -text       #查看证书

#方法2
[root@centos7 ~]#mkdir /etc/haproxy/certs/
[root@centos7 ~]#cd /etc/pki/tls/certs
[root@centos7 certs]#make /etc/haproxy/certs/haproxy.pem
umask 77 ; \
PEM1=/bin/mktemp /tmp/openssl.XXXXXX ; \
PEM2=/bin/mktemp /tmp/openssl.XXXXXX ; \
/usr/bin/openssl req -utf8 -newkey rsa:2048 -keyout PEM1 -nodes -x509 -days 365
-outPEM2 ; \
cat PEM1> /etc/haproxy/certs/haproxy.pem ; \
echo ""   >> /etc/haproxy/certs/haproxy.pem ; \
catPEM2 >> /etc/haproxy/certs/haproxy.pem ; \
rm -f PEM1PEM2
Generating a 2048 bit RSA private key
.+++
..............................................+++
writing new private key to '/tmp/openssl.x8hOA8'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:beijing
Locality Name (eg, city) [Default City]:beijing
Organization Name (eg, company) [Default Company Ltd]:openlab
Organizational Unit Name (eg, section) []:it
Common Name (eg, your name or your server's hostname) []:www.openlab.org
Email Address []:
[root@centos7 certs]#ll /etc/haproxy/certs/
total 4
-rw------- 1 root root 3027 Apr  4 10:35 haproxy.pem

https配置示例

[root@centos7 ~]#cat /etc/haproxy/conf.d/test.cfg
frontend openlab_http_port
    bind 10.0.0.7:80
    bind 10.0.0.7:443 ssl crt /etc/haproxy/certs/haproxy.pem
    redirect scheme https if !{ ssl_fc }        # 注意{ }内的空格
    http-request set-header X-forwarded-Port   %[dst_port]
    http-request add-header X-forwarded-Proto https if { ssl_fc }
    mode http
    balance roundrobin
    log global
    option httplog
###################### acl setting ###############################
    acl mobile_domain hdr_dom(host)   -i mobile.openlab.org
###################### acl hosts #################################
    default_backend pc_hosts
################### backend hosts #################################
backend mobile_hosts
    mode http
    server web1 10.0.0.17:80 check inter 2000 fall 3 rise 5

backend pc_hosts
    mode http
    #http-request set-header X-forwarded-Port   %[dst_port] 也可加在此处
    #http-request add-header X-forwarded-Proto https if { ssl_fc }
    server web2 10.0.0.27:80 check inter 2000 fall 3 rise 5

[root@centos7 ~]#ss -ntl
State     Recv-Q Send-Q         Local Address:Port   Peer Address:Port        
     
LISTEN     0      100                 127.0.0.1:25                 *:*          
       
LISTEN     0      128                  10.0.0.7:443               *:*         

LISTEN     0      128                         *:9999               *:*          
       
LISTEN     0      128                  10.0.0.7:80                 *:*          
       
LISTEN     0      128                         *:22                 *:*          
       
LISTEN     0      128                     [::]:22                 [::]:*  

修改后端服务器的日志格式

[root@centos27 ~]#vim /etc/httpd/conf/httpd.conf
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" \"%{X-
Forwarded-Port}i\" \"%{X-Forwarded-Proto}i\"" combined  

验证https

[root@centos6 ~]#curl -IkL http://www.openlab.org
HTTP/1.1 302 Found
content-length: 0
location: https://www.openlab.org/
cache-control: no-cache

HTTP/1.1 200 OK
date: Sat, 04 Apr 2020 02:31:31 GMT
server: Apache/2.4.6 (CentOS) PHP/5.4.16
last-modified: Thu, 02 Apr 2020 01:44:13 GMT
etag: "a-5a244f01f8adc"
accept-ranges: bytes
content-length: 10
content-type: text/html; charset=UTF-8

[root@centos6 ~]#curl -Ik https://www.openlab.org
HTTP/1.1 200 OK
date: Sat, 04 Apr 2020 02:31:50 GMT
server: Apache/2.4.6 (CentOS) PHP/5.4.16
last-modified: Thu, 02 Apr 2020 01:44:28 GMT
etag: "a-5a244f0fd5175"
accept-ranges: bytes
content-length: 10
content-type: text/html; charset=UTF-8

#查看后端服务器的访问日志
[root@centos27 ~]#tail /var/log/httpd/access_log
10.0.0.7 - - [04/Apr/2020:10:40:17 +0800] "HEAD / HTTP/1.1" 200 - "-"
"curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.27.1 zlib/1.2.3
libidn/1.18 libssh2/1.4.2" "443" "https"

3、 负载均衡关键技术

1、什么是 Session

  • Session 在网络中应该被称之为“会话”,借助它可提供服务器端与客户端系 统之间必要的交互 。 因为HTTP 协议本身是无状态的,所以经常需要通过 Session 来提供服务端和浏览端的保持状态的解决方案。 Session 是由应用服务器维持的一个服务器端的存储空间,用户在连接服务器时,会由服务器生成一个唯一的 SessionID ,该 SessionID 作为标识符来存取服务器端的 Sess ion 存储空间 。
  • SessionID 这一数据是用 Cookie 保存到客户端的,用户提交页面时,会将这一 SessionID提交到服务器端,以此存取 Session 数据 。 服务器也通过 URL 重写的方式来传递 SessionID的值,因此它不是完全依赖于 Cookie 的 。 如果客户端 Cookie 禁用,则服务器可以自动通过重写 URL 的方式来保存 Session的值,并且这个过程对程序员是透明的 。

2、什么是 Session 共享

        当网站业务规模和访问量逐步增大,原本由单台服务器、单个域名组成的迷你网站架构可能已经无法满足发展需要 。

        此时,我们可能会购买更多的服务器,并且以频道化的方式启用多个二级子域名 ,然后根据业务功能将网站分别部署在独立的服务器上,或者通过负载均衡技术(如 Haproxy 、Nginx )让多个频道共享一组服务器 。

        如果我们把网站程序分别部署到多台服务器上,并且独立为几个二级域名,由 于Session 存在实现原理上的局限性( PHP 中 Session 默认以文件的形式保存在本地服务器的硬盘上),这使得网站用户不得不经常在几个频道间来回输入用户名和密码登录,导致用户体验大打折扣 。 另外,原本程序可以直接从用户 Session 变量中读取的资料(如:昵称 、 积分、登入时间等),因为无法跨服务器同步更新 Session变量,迫使开发人员必须实时读写数据库,从而增加了数据库的负担 。 于是,解决网站跨服务器的Session 共享问题的需求变得越来越迫切,最终催生了多种解决方案,下面列举 4 种较为可行的方案进行对比和探讨。

1、基于 Cookie 的 Session 共事

        读者可能对这个方案比较陌生,但它在大型网站中已被普遍使用 。 其原理是将全站用户的 Session 信息加密,序列化后以 Cookie 的方式统一种植在根域名下(如: .host.com ) 。

        当浏览器访问该根域名下的所有二级域名站点时,将与域名相对应的所有 Cookie 内容的特性传递给它,从而实现用户的 Cookie 化 Session 在多服务间的共享访问 。这个方案的优点是无须额外的服务器资源,缺点是由于受 HTTP 协议头长度的限制,仅能存储小部分的用户信息,同时 Cookie 化的 Session 内容需要进行安全加解密(如:采用 DES 、 RSA 等进行明文加解密;再由 MDS, SHA-1 等算法进行防伪认证) 。 另外,它也会占用一定的带宽资源,因为浏览器会在请求当前域名下的任何资源时将本地 Cookie 附加在 HTTP 头中传递到服务器上 。

2、基于数据库的 Session 共享

        首选的当然是 MySQL 数据库,并且建议使用内存表 Heap ,以提高 Session 操作的读写效率。 这个方案的实用性较强,已得到大家的普遍使用,但它的缺点在于 Session 的并发读写能力取决于 MySQL 数据库的性能,同时需要我们自己实现 Session 淘汰逻辑,以便定时从数据表中更新 、 删除 Session 记录,当并发过高时容易出现表锁,虽然我们可以选择行级锁的表引擎,但不得不承认使用数据库存储 Session 还是有些大材小用了 。

3、Session 复制

        熟悉 Tomcat 或 Weblogic 的应该对 Session 复制也非常了解了 。 顾名思义, Session复制就是将用户的 Session 复制到 Web 集群内的所有服务器, Tomcat 或 Weblogic 自身都带了这种处理机制 。 但其缺点也非常明显:随着机器数量的增加,网络负担成指数级上升,性能随着服务器数量的增加而急剧下降,而且很容易引起网络风暴 。

4、基于 Memcache/Redis 的 Session 共享

        Memcache 是一款基于 Libevent 的多路异步 1/0 技术的内存共享系统,简单的 Key+Value 数据存储模式使其代码逻辑小巧高效,因此在并发处理能力上占据了绝对优势 。另外值得一提的是 Memcache 的内存 hash 表所特有的 Expires 数据过期淘汰机制,正好和 Session 的过期机制不谋而合,这就降低了删除过期 Session 数据的代码复杂度 。 但对比“基于数据库的存储方案”,仅逻辑这块就给数据表带来了巨大的查询压力 。

        Redis 作为 NoSQL 的后起之秀,经常被来与 memcached 做对比 。 red is 作为 一种缓存,或者干脆称之为 NoSQL 数据库,提供了丰富的数据类型( list 、 set 等),可以将大量数据的排序从单机内存释放到 redis 集群中处理,并可以用于实现轻量级消息中间件 。 在memcached 和 redis 的性能比较上, redis 在小于 lOOk 的数据读写上速度优于 memcached 。

3、什么是会话保持

会话保持并非 Session 共享。

        在大多数的电子商务应用系统中,或者需要进行用户身份认证的在线系统中,一个客户与服务器经常会经过好几次的交互过程才能完成一笔交易或一个请求 。 由于这几次交互过程是密切相关的,服务器在进行这些交互的过程中,要完成某一个交互步骤往往需要了解上一次交互的处理结果,或者前几步的交互结果,这就要求所有相关的交互过程都由一台服务器完成,而不能被负载均衡器分散到不同的服务器上。

        而这一系列相关的交互过程可能是由客户到服务器的一个连接的多次会话完成的,也可能是在客户与服务器之间的多个不同连接里的多次会话完成的 。 关于不同连接的多次会话,最典型的例子就是基于HTTP 的访问,一个客户完成一笔交易可能需要多次点击,而一个新的点击产生的请求,可能会重用上一次点击建立起来的连接,也可能是一个新建的连接。

        会话保持就是指在负载均衡器上有这么一种机制,可以识别客户与服务器之间交互过程的关联性,在做负载均衡的同时 , 还能保证一系列相关联的访问请求被分配到同一台服务器上 。

负载均衡器实现会话保持一般会有如下几种方案 :

  1. 基于源 IP 地址的持续性保持。 主要用于四层负载均衡,这种方案应该是大家最为熟悉的,LVS/HAProxy 、 Nginx 都有类似的处理机制,如 Nginx 中的 ip_hash 算法,HAProxy 中的 source 算法等 。
  2. 基于 Cookie 数据的持续性保持 。 主要用于七层负载均衡,用 于确保同 一会话的报文能够被分配到同一台服务器中 。 其中,根据服务器的应答报文中是否携带含有服务器信息的 Set Cookie 字段,又可以分为 cookie 插入保持和 cookie 截取保持。
  3. 基于 HTTP 报文头的持续性保持 。 主要用于七层负载均衡,当负载均衡器接收到某一个客户端的首次请求时,会根据 HTTP 报文头关键字建立持续性表项,记录为该客户端分配的服务器情况,在会话表项的生存期内,后续具有相同 HTTP 报文头信息的连接都将发往该服务器处理。


http://www.niftyadmin.cn/n/5868938.html

相关文章

python爬虫学习第十一篇爬取指定类型数据

最近在学习Python爬虫的过程中,尝试用爬虫获取指定类型的数据。今天,我想和大家分享一下我的实践过程和遇到的问题。 一、实现目标 目标是从一个网站的API接口获取不同类型的食品数据。 比如,第一步我想获取汉堡、小食、甜品等不同类型的数…

ROS的action通信——实现阶乘运算(三)

在ROS中除了常见的话题(topic)通信、服务(server)通信等方式,还有action通信这一方式,由于可以实时反馈任务完成情况,该通信方式被广泛运用于机器人导航等任务中。本文将通过三个小节的分享,实现基于action通信的阶乘运…

Linux 第三次脚本作业

源码编译安装httpd 2.4,提供系统服务管理脚本并测试(建议两种方法实现) 一、第一种方法 1、把 httpd-2.4.63.tar.gz 这个安装包上传到你的试验机上 2、 安装编译工具 (俺之前已经装好了) 3、解压httpd包 4、解压后的httpd包的文…

【前端基础】Day 1 HTML

总结: 1. Web标准的构成 2. 基本标签 目录 1. Web标准的构成 2. 基本标签 2.1快捷键 2.2.1标题标签 2.2.2段落和换行标签 2.2.3文本格式化标签 2.2.4div和span标签 2.3.1 图像标签和路径 2.3.2路径 2.3.3超链接标签 2.4注释标签 2.5特殊字符 1. Web标准…

【前沿探索篇九】【DeepSeek具身智能:机器人操作学习框架】

第一章 具身智能的"五感觉醒" 1.1 多模态感知的神经交响乐 我们的多模态编码器就像机器人的大脑皮层,把不同传感器数据拧成一股绳: class MultimodalEncoder(nn.Module):def __init__(self):sel

电脑不能正常启动了怎么办?查看解决方法

电脑是我们日常生活和工作中不可缺少的工具,但有时候我们可能会遇到电脑不能正常启动的问题,这会给我们带来很多麻烦和困扰。那么,电脑不能正常启动的原因有哪些,又该如何解决呢?本文将为你介绍几种常见的情况和对应的…

STM32【3】芯片的底层组成概论

关于单片机的组成 单片机的意思是,小小计算电脑,麻雀虽小,五脏俱全,里面包含了CPU,ROM,RAM,各种外设。 CPU地位最高,可以访问ROM和RAM,Flash,GPIO等外设&…

面试基础----ReentrantLock vs Synchronized

ReentrantLock vs Synchronized:源码级解析与高并发场景下的锁博弈 引言:多线程编程中的锁为何重要? 业务背景:北京互联网大厂的高并发场景(如电商秒杀、支付交易、实时推荐系统)对线程安全和性能的极致要…