nginx是一款高性能的http 服務器/反向代理服務器及電子郵件(IMAP/POP3)代理服務器。由俄羅斯的程序設計師Igor Sysoev所開發,官方測試nginx可以支支撐5萬併發連接,而且cpu、內存等資源消耗卻很是低,運行很是穩定,因此如今不少知名的公司都在使用nginx。html
Nginx、lvs、F5(硬件)、haproxyjava
一、http服務器。Nginx是一個http服務能夠獨立提供http服務。能夠作網頁靜態服務器。linux
二、虛擬主機。能夠實如今一臺服務器虛擬出多個網站。例如我的網站使用的虛擬主機。nginx
三、反向代理,負載均衡。當網站的訪問量達到必定程度後,單臺服務器不能知足用戶的請求時,須要用多臺服務器集羣可使用nginx作反向代理。而且多臺服務器能夠平均分擔負載,不會由於某臺服務器負載高宕機而某臺服務器閒置的狀況。c++
解壓:nginx-windowsweb
雙擊: nginx.exeredis
能看到nginx歡迎界面說明,nginx安裝成功算法
演示下 nginx作靜態服務器spring
nginx.exe -s stop #中止
佔內存小,能夠實現高併發鏈接、處理響應快。數據庫
能夠實現http服務器、虛擬主機、反向代理、負載均衡。
nginx配置簡單
能夠不暴露真實服務器IP地址
nginx的配置由特定的標識符(指令符)分爲多個不一樣的模塊。
指令符分爲簡單指令和塊指令。
conf文件中,全部不屬於塊指令的簡單指令都屬於main上下文的,http塊指令屬於main上下文,server塊指令http上下文。
Web server很重要一部分工做就是提供靜態頁面的訪問,例如images, html page。nginx能夠經過不一樣的配置,根據request請求,從本地的目錄提供不一樣的文件返回給客戶端。
打開安裝目錄下的nginx.conf文件,默認配置文件已經在http指令塊中建立了一個空的server塊,在nginx-1.8.0中的http塊中已經建立了一個默認的server塊。內容以下:
server { listen 80; server_name localhost; location / { root html; index index.html index.htm; } error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } }
反向代理(Reverse Proxy)方式是指以代理服務器來接受internet上的鏈接請求,而後將請求轉發給內部網絡上的服務器,並將從服務器上獲得的結果返回給internet上請求鏈接的客戶端,此時代理服務器對外就表現爲一個反向代理服務器。
啓動一個Tomcat 127.0.0.1:8080
使用nginx反向代理 8080.itmayiedu.com 直接跳轉到127.0.0.1:8080
127.0.0.1 8080.hongmoshui.com
127.0.0.1 8081.hongmoshui.com
配置信息:
server { listen 80; server_name 8080.hongmoshui.com; location / { proxy_pass http://127.0.0.1:8080; index index.html index.htm; } } server { listen 80; server_name 8081.hongmoshui.com; location / { proxy_pass http://127.0.0.1:8081; index index.html index.htm; } }
負載均衡 創建在現有網絡結構之上,它提供了一種廉價有效透明的方法擴展網絡設備和服務器的帶寬、增長吞吐量、增強網絡數據處理能力、提升網絡的靈活性和可用性。
負載均衡,英文名稱爲Load Balance,其意思就是分攤到多個操做單元上進行執行,例如Web服務器、FTP服務器、企業關鍵應用服務器和其它關鍵任務服務器等,從而共同完成工做任務。
一、輪詢(默認)
每一個請求按時間順序逐一分配到不一樣的後端服務器,若是後端服務器down掉,能自動剔除。
upstream backserver { server 192.168.0.14; server 192.168.0.15; }
2、指定權重
指定輪詢概率,weight和訪問比率成正比,用於後端服務器性能不均的狀況。
upstream backserver { server 192.168.0.14 weight=10; server 192.168.0.15 weight=10; }
3、IP綁定 ip_hash
每一個請求按訪問ip的hash結果分配,這樣每一個訪客固定訪問一個後端服務器,能夠解決session的問題。
upstream backserver { ip_hash; server 192.168.0.14:88; server 192.168.0.15:80; }
4、fair(第三方)
按後端服務器的響應時間來分配請求,響應時間短的優先分配。
upstream backserver {
server server1;
server server2;
fair;
}
五、url_hash(第三方)
按訪問url的hash結果來分配請求,使每一個url定向到同一個後端服務器,後端服務器爲緩存時比較有效。
upstream backserver { server squid1:3128; server squid2:3128; hash $request_uri; hash_method crc32; }
upstream backserver { server 127.0.0.1:8080; server 127.0.0.1:8081; } server { listen 80; server_name www.hongmoshui.com; location / { proxy_pass http://backserver; index index.html index.htm; } }
server { listen 80; server_name www.itmayiedu.com; location / { proxy_pass http://backserver; index index.html index.htm; proxy_connect_timeout 1; proxy_send_timeout 1; proxy_read_timeout 1; } }
配置:
server { listen 80; server_name www.itmayiedu.com; location /A { proxy_pass http://a.a.com:81/A; index index.html index.htm; } location /B { proxy_pass http://b.b.com:81/B; index index.html index.htm; } }
location ~ .*\.(jpg|jpeg|JPG|png|gif|icon)$ { valid_referers blocked http://www.itmayiedu.com www.itmayiedu.com; if ($invalid_referer) { return 403; } }
設置Nginx、Nginx Plus的鏈接請求在一個真實用戶請求的合理範圍內。好比,若是你以爲一個正經常使用戶每兩秒能夠請求一次登陸頁面,你就能夠設置Nginx每兩秒鐘接收一個客戶端IP的請求(大約等同於每分鐘個請求)。
limit_req_zone $binary_remote_addr zone=one:10m rate=2r/s; server { ... location /login.html { limit_req zone=one; ... } }
limit_req_zone`命令設置了一個叫one的共享內存區來存儲請求狀態的特定鍵值,在上面的例子中是客戶端IP($binary_remote_addr)。location塊中的`limit_req`經過引用one共享內存區來實現限制訪問/login.html的目的。
設置Nginx、Nginx Plus的鏈接數在一個真實用戶請求的合理範圍內。好比,你能夠設置每一個客戶端IP鏈接/store不能夠超過10個。
漏桶算法能夠很好地限制容量池的大小,從而防止流量暴增。若是針對uri+ip做爲監測的key,就能夠實現定向的設定指定ip對指定uri容量大小,超出的請求作隊列處理(隊列處理要引入消息機制)或者丟棄處理。這也是v2ex對流量攔截的算法,針對uri+ip作流量監測。
Nginx是一款輕量級的網頁服務器、反向代理服務器。相較於Apache、lighttpd具備佔有內存少,穩定性高等優點。它最常的用途是提供反向代理服務。
在Centos下,yum源不提供nginx的安裝,能夠經過切換yum源的方法獲取安裝。也能夠經過直接下載安裝包的方法,如下命令均需root權限執行:
首先安裝必要的庫(nginx 中gzip模塊須要 zlib 庫,rewrite模塊須要 pcre 庫,ssl 功能須要openssl庫)。選定/usr/local爲安裝目錄,如下具體版本號根據實際改變。
$ cd /usr/local/ $ wget ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-8.36.tar.gz $ tar -zxvf pcre-8.36.tar.gz $ cd pcre-8.36 $ ./configure $ make $ make install
./configure報錯
configure: error: You need a C++ compiler for C++ support.
解決辦法
yum install -y gcc gcc-c++
$ cd /usr/local/ $ wget http://zlib.net/zlib-1.2.8.tar.gz $ tar -zxvf zlib-1.2.8.tar.gz $ cd zlib-1.2.8 $ ./configure $ make $ make install
$ cd /usr/local/ $ wget http://www.openssl.org/source/openssl-1.0.1j.tar.gz $ tar -zxvf openssl-1.0.1j.tar.gz $ ./config $ make $ make install
$ cd /usr/local/ $ wget http://nginx.org/download/nginx-1.8.0.tar.gz $ tar -zxvf nginx-1.8.0.tar.gz $ cd nginx-1.8.0 $ ./configure --prefix=/usr/local/nginx $ make $ make install
安裝常見錯誤:
Nginx啓動提示找不到libpcre.so.1解決方法
若是是32位系統
[root@lee ~]# ln -s /usr/local/lib/libpcre.so.1 /lib
若是是64位系統
[root@lee ~]# ln -s /usr/local/lib/libpcre.so.1 /lib64
而後在啓動nginx就OK了
[root@lee ~]# /usr/local/webserver/nginx/sbin/nginx
$ /usr/local/nginx/sbin/nginx
檢查是否啓動成功:
打開瀏覽器訪問此機器的 IP,若是瀏覽器出現 Welcome to nginx! 則表示 Nginx 已經安裝並運行成功。
重啓:
$ /usr/local/nginx/sbin/nginx 啓動命令
重啓:
$ /usr/local/nginx/sbin/nginx –s reload
中止:
$ /usr/local/nginx/sbin/nginx –s stop
測試配置文件是否正常:
$ /usr/local/nginx/sbin/nginx –t
強制關閉:
$ pkill nginx
Keepalived是一個免費開源的,用C編寫的相似於layer3, 4 & 7交換機制軟件,具有咱們平時說的第3層、第4層和第7層交換機的功能。主要提供loadbalancing(負載均衡)和 high-availability(高可用)功能,負載均衡實現須要依賴Linux的虛擬服務內核模塊(ipvs),而高可用是經過VRRP協議實現多臺機器之間的故障轉移服務。
上圖是Keepalived的功能體系結構,大體分兩層:用戶空間(user space)和內核空間(kernel space)。
內核空間:主要包括IPVS(IP虛擬服務器,用於實現網絡服務的負載均衡)和NETLINK(提供高級路由及其餘相關的網絡功能)兩個部份。
用戶空間:
Keepalived的全部功能是配置keepalived.conf文件來實現的。
下載keepalived地址:http://www.keepalived.org/download.html
解壓安裝:
tar -zxvf keepalived-1.2.18.tar.gz -C /usr/local/ yum install -y openssl openssl-devel(須要安裝一個軟件包) cd keepalived-1.2.18/ && ./configure --prefix=/usr/local/keepalived make && make install
將keepalived安裝成Linux系統服務,由於沒有使用keepalived的默認安裝路徑(默認路徑:/usr/local),安裝完成以後,須要作一些修改工做:
首先建立文件夾,將keepalived配置文件進行復制:
mkdir /etc/keepalived
cp /usr/local/keepalived/etc/keepalived/keepalived.conf /etc/keepalived/
而後複製keepalived腳本文件:
cp /usr/local/keepalived/etc/rc.d/init.d/keepalived /etc/init.d/ cp /usr/local/keepalived/etc/sysconfig/keepalived /etc/sysconfig/ ln -s /usr/local/sbin/keepalived /usr/sbin/ ln -s /usr/local/keepalived/sbin/keepalived /sbin/
能夠設置開機啓動:
chkconfig keepalived on
到此咱們安裝完畢!
service keepalived start
service keepalived stop
第三步:對配置文件進行修改:vim /etc/keepalived/keepalived.conf
keepalived.conf配置文件說明:
(一)Master
!Configuration File for keepalived global_defs { router_id bhz005 ##標識節點的字符串,一般爲hostname }
## keepalived 會定時執行腳本而且對腳本的執行結果進行分析,動態調整vrrp_instance的優先級。這裏的權重weight 是與下面的優先級priority有關,若是執行了一次檢查腳本成功,則權重會-20,也就是由100 - 20 變成了80,Master 的優先級爲80 就低於了Backup的優先級90,那麼會進行自動的主備切換。
若是腳本執行結果爲0而且weight配置的值大於0,則優先級會相應增長。
若是腳本執行結果不爲0 而且weight配置的值小於0,則優先級會相應減小。
vrrp_script chk_nginx { script "/etc/keepalived/nginx_check.sh" ##執行腳本位置 interval 2 ##檢測時間間隔 weight -20 ## 若是條件成立則權重減20(-20) }
## 定義虛擬路由 VI_1爲自定義標識。
vrrp_instance VI_1 { state MASTER ## 主節點爲MASTER,備份節點爲BACKUP ## 綁定虛擬IP的網絡接口(網卡),與本機IP地址所在的網絡接口相同(我這裏是eth6) interface eth6 virtual_router_id 172 ## 虛擬路由ID號 mcast_src_ip 192.168.1.172 ## 本機ip地址 priority 100 ##優先級配置(0-254的值) Nopreempt ## advert_int 1 ## 組播信息發送間隔,倆個節點必須配置一致,默認1s authentication { auth_type PASS auth_pass bhz ## 真實生產環境下對密碼進行匹配 } track_script { chk_nginx } virtual_ipaddress { 192.168.1.170 ## 虛擬ip(vip),能夠指定多個 } }
(二)Backup
!Configuration File for keepalived global_defs { router_id bhz006 } vrrp_script chk_nginx { script "/etc/keepalived/nginx_check.sh" interval 2 weight -20 } vrrp_instance VI_1 { state BACKUP interface eth7 virtual_router_id 173 mcast_src_ip 192.168.1.173 priority 90 ##優先級配置 advert_int 1 authentication { auth_type PASS auth_pass bhz } track_script { chk_nginx }
virtual_ipaddress { 192.168.1.170 } }
(三)nginx_check.sh 腳本:
#!/bin/bash A=`ps -C nginx –no-header |wc -l` if [ $A -eq 0 ];then /usr/local/nginx/sbin/nginx sleep 2 if [ `ps -C nginx --no-header |wc -l` -eq 0 ];then killall keepalived fi fi
(四)咱們須要把master的keepalived配置文件 copy到master機器(172)的 /etc/keepalived/ 文件夾下,在把backup的keepalived配置文件copy到backup機器(173)的 /etc/keepalived/ 文件夾下,最後把nginx_check.sh腳本分別copy到兩臺機器的 /etc/keepalived/文件夾下。
(五)nginx_check.sh腳本受權。賦予可執行權限:chmod +x /etc/keepalived/nginx_check.sh
(六)啓動2臺機器的nginx以後。咱們啓動兩臺機器的keepalived
/usr/local/nginx/sbin/nginx service keepalived start ps -ef | grep nginx ps -ef | grep keepalived
能夠進行測試,首先看一下倆臺機器的ip a 命令下 都會出現一個虛擬ip,咱們能夠停掉 一個機器的keepalived,而後測試,命令:service keepalived stop。結果發現當前停掉的機器已經不可用,keepalived會自動切換到另外一臺機器上。
(七)咱們能夠測試在nginx出現問題的狀況下,實現切換,這個時候咱們只須要把nginx的配置文件進行修改,讓其變得不可用,而後強殺掉nginx進程便可,發現也會實現自動切換服務器節點。
建立一個springboot項目 實現負載均衡
用Nginx 作的負載均衡能夠添加ip_hash這個配置,
用haproxy作的負載均衡能夠用 balance source這個配置。
從而使同一個ip的請求發到同一臺服務器。
缺點:安全性差、http請求都須要帶參數增長了帶寬消耗
建立一個springboot項目
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.hongmoshui.www</groupId> <artifactId>redis</artifactId> <version>0.0.1-SNAPSHOT</version> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.3.RELEASE</version> </parent> <dependencies> <!--spring boot 與redis應用基本環境配置 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <!--spring session 與redis應用基本環境配置,須要開啓redis後纔可使用,否則啓動Spring boot會報錯 --> <dependency> <groupId>org.springframework.session</groupId> <artifactId>spring-session-data-redis</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies> </project>
package com.hongmoshui.session; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession; //這個類用配置redis服務器的鏈接 //maxInactiveIntervalInSeconds爲SpringSession的過時時間(單位:秒) @EnableRedisHttpSession(maxInactiveIntervalInSeconds = 1800) public class SessionConfig { // 冒號後的值爲沒有配置文件時,制動裝載的默認值 @Value("${redis.hostname:localhost}") String HostName; @Value("${redis.port:6379}") int Port; @Value("${redis.password:123456}") String Password; @Bean public JedisConnectionFactory connectionFactory() { JedisConnectionFactory connection = new JedisConnectionFactory(); connection.setPort(Port); connection.setHostName(HostName); connection.setPassword(Password); return connection; } }
package com.hongmoshui.session; import org.springframework.session.web.context.AbstractHttpSessionApplicationInitializer; //初始化Session配置 public class SessionInitializer extends AbstractHttpSessionApplicationInitializer { public SessionInitializer() { super(SessionConfig.class); } }
package com.hongmoshui.controller; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.SpringApplication; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class SessionController { @Value("${server.port:8080}") private String PORT; public static void main(String[] args) { SpringApplication.run(SessionController.class, args); } @RequestMapping("/index") public String index() { return "index:" + PORT; } /** * 往session存放值 * @param request * @param sessionKey * @param sessionValue * @author 墨水 */ @RequestMapping("/setSession") public String setSession(HttpServletRequest request, String sessionKey, String sessionValue) { HttpSession session = request.getSession(true); session.setAttribute(sessionKey, sessionValue); return "success,port:" + PORT; } /** * 從Session獲取值 * @param request * @param sessionKey * @author 墨水 */ @RequestMapping("/getSession") public String getSession(HttpServletRequest request, String sessionKey) { HttpSession session = null; try { session = request.getSession(false); } catch (Exception e) { e.printStackTrace(); } String value = null; if (session != null) { value = (String) session.getAttribute(sessionKey); } return "sessionValue:" + value + ",port:" + PORT; } }
package com.hongmoshui; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class StartApp { public static void main(String[] args) { SpringApplication.run(StartApp.class, args); } }
業務數據庫 -》 數據水平分割(分區分表分庫)、讀寫分離
業務應用 -》 邏輯代碼優化(算法優化)、公共數據緩存
應用服務器 -》 反向靜態代理、配置優化、負載均衡(apache分發,多tomcat實例)
系統環境 -》 JVM調優
頁面優化 -》 減小頁面鏈接數、頁面尺寸瘦身
一、動態資源和靜態資源分離;
二、CDN;
三、負載均衡;
四、分佈式緩存;
五、數據庫讀寫分離或數據切分(垂直或水平);
六、服務分佈式部署。