Nginx (engine x) 是一个高性能的HTTP和反向代理web服务器,同时也提供了IMAP/POP3/SMTP服务。它是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,在BSD-like 协议下发行。其特点是占有内存少,并发能力强,事实上nginx的并发能力在同类型的网页服务器中表现较好,中国大陆使用nginx网站用户有:百度、京东、新浪、网易、腾讯、淘宝等。
什么是负载均衡
负载均衡(Load Balance),是一种通过程序的方式来管理分布式服务器的策略,有个形象的例子,就是我们程序猿日常开发一个需求的过程一样,客户就是我们的客户端,需求就相当于是请求,PM就负责负载均衡的程序,PM接到客户的需求,这时候就会根据我们每个人的情况给我们这些程序猿分配任务,我们接到任务之后就会各司其职,开始码代码,过程中要是有人请假了或者什么原因不能码代码了,PM就会让别人接手他的工作,而客户根本不知道他提的需求代码是谁写的,他只知道提需求是提给我们的PM,PM会了解我们每个人的工作饱和度,不会让有人的工作量太过饱和或者不饱和,我们管这种调度策略叫做负载均衡。
代理
代理分为两种:正向代理和反向代理
- 正向代理:
正向代理(Forward Proxy)最大的特点就是,客户端知道自己要访问的是哪一台服务器,代理服务器代理客户端向服务器发送请求,而被访问的服务器只知道访问自己的是代理服务器,而并不清楚真正访问自己的是哪一个客户端。比如科学上网,俗称翻墙,还有咱们玩游戏的时候的各种加速器。
一次正向代理的过程大致是这样:客户端告诉代理服务器,我想访问xxxxx,然后代理服务器代替客户端向xxxxx发送请求,在接受到xxxxx的返回结果后告诉客户端返回结果。 - 反向代理:
反向代理(Reverse Proxy)则是刚好相反,它是后端的代理服务器,这时候客户端也不知道具体处理自己请求的是哪一台服务器了,他只知道自己的请求要发送给这个代理服务器,然后这个服务器再根据一定的策略将请求分配给不同的服务器去处理,最后将返回的结果告诉客户端。
Nginx是什么
Nginx是一种基于c实现的高性能Web服务器,可以通过一些负载均衡算法解决负载均衡的问题。因为它具有高并发、高可靠性、高扩展性、开源等特点,成为开发人员常用的反向代理工具。
负载均衡常用算法
1.轮询 (round-robin)
轮询是负载均衡算法中最基础最简单的算法,它不需要额外的配置参数。假设配置文件中共有N台服务器,该算法就会按照这N台服务器的次序依次选择一台服务器处理请求,当所有的服务器都被调用过一次之后,就会从第一台服务器重新开始新一轮的遍历。
特点: 这种算法不考虑服务器性能的差距,适用于集群的各台服务器性能相差不大的情况,对于服务器性能差距较大的情况,容易引发资源分配不合理的情况出现。
express模拟轮询处理请求:
proxyServer.js:
const express = require("express");
const app = new express();
const http = require("http");
const servers = [
{ weight: 10, host: "http://localhost", port: 8088, id: 0 },
{ weight: 9, host: "http://localhost", port: 8089, id: 1 }
];
const port = 8087;
let currentServer = null;
let currentIndex = 0;
app.get("/", (req, res) => {
if (currentIndex === servers.length - 1) {
currentIndex = 0;
} else {
currentIndex++;
}
currentServer = servers[currentIndex];
http.get(`${currentServer.host}:${currentServer.port}`, res1 => {
console.log("proxy success");
let data = "";
res1.on("data", chunk => {
data += chunk;
});
res1.on("end", () => {
res.send(data);
});
});
});
app.listen(port, () => {
console.log(`success:${port}`);
});
server1.js:
const express = require ('express');
const app = new express();
const port = 8088;
app.get('/', (req,res)=>{
res.send(`Hello World! I am port ${port}~`)
})
app.listen(port,()=>{console.log(`success:${port}`)})
server2.js:
const express = require ('express');
const app = new express();
const port = 8089;
app.get('/', (req,res)=>{
res.send(`Hello World! I am port ${port}~`)
})
app.listen(port,()=>{console.log(`success:${port}`)})
2. 加权轮询
为了避免普通轮询带来的弊端,使用一个权值来表示服务器性能,权值越高表示服务器性能越强,这就有点类似于我们平时说的 “能力越强,责任越大”,其实说白了就是会的多就多干点活。在这种酸中,客户端的请求按照权值比例分配,当一个请求到达的时候,优先分配权值大的服务器去处理请求。
特点:加权轮询可以适用于服务器性能层次不齐的集群中,使资源分配更加合理。
加权轮询的核心思想就是 “能者多劳” ,性能越强的服务器被选中的几率越大。
3. IP哈希(IP hash)
ip hash 使依据发出请求的客户端IP来决定由哪一台服务器来处理请求,这种算法可以保证相同IP发送的请求分配给同一台服务器来处理,或者带有相同hash值的不通IP映射到同一台服务器。
特点: 这种策略一定程度上解决了集群部署的情况下,Session不共享的问题。
4. 最小连接数策略
当反向代理服务器接收到客户端发来的请求时,去遍历服务器列表并且将请求分配给当前处理请求最少的那一台服务器,这个就类似于,PM觉得你工作不饱和就会给你分配新的任务一样。