JT項目-2

DAY03

知識回顧

2018113

8:58

 

1 parent和common

2 搭建了後臺系統

3 商品分類的全部內容展示(測試)

京淘中的表格設計

京淘中的所有表格都是單表設計

沒有外鍵關聯;

提高系統的性能;

涉及到多表的關係,是代碼

4 後臺的頁面跳轉

restFul傳參

 

 

商品分類樹的展示

2018113

9:07

匯通中我們使用Ztree樹

 

但是京淘中使用的是EasyUI的封裝

 

EasyUI介紹

是一組基於jquery的UI插件集合;目的是幫助開發者輕鬆

地打造豐富功能且美觀的UI界面;使用EasyUI不必瞭解複雜的js

jquery代碼,只需要知道一些簡單的HTML標籤;

在京淘中見到最多的EasyUI當中的一個屬性

data-options

 

EasyUI在京淘中的使用

後臺頁面樣式就使用的是EasyUI

佈局效果

 

這裏直接訪問item-add沒有樣式的引入

EasyUI的頁面佈局使用的是div+css

所有的彈出子窗口或者頁夾都是一個div,div可以做頁面的局部刷新

但是css,js資源的引入div需要依賴父頁面

 

觀察了index.jsp並沒有發現引用的資源

include

 

index.jsp最終easyUI的一些特點

1 佈局layout

data-options="region:'west',title:'菜單',split:true"

west:頁面西側

titel:div名稱

split:可否伸縮

2 靜態菜單

<li data-options="attributes:{'url':'/page/item-add'}">新增商品</li>

<li data-options="attributes:{'url':'/page/item-list'}">查詢商品</li>

<li data-options="attributes:{'url':'/page/item-param-list'}">規格參數</li>

3 頁夾        

<div id="tabs" class="easyui-tabs">

    <div title="首頁" style="padding:20px;">

                

    </div>

</div>

 在靜態菜單中選擇一個頁面將會自動填充到div 首頁中

4 新增頁面

選擇按鈕是一個a標籤

<a href="javascript:void(0)" class="easyui-linkbutton selectItemCat">選擇類目</a>

easyUI修飾的a標籤

5 彈出的分類窗口

6 新增商品中的一些data-options屬性

商品標題:data-options="required:true" 必填項

商品賣點:data-options="multiline:true,validType:'length[0,150]'"

multiline:多行輸入

validType:輸入大小範圍

價格:data-options="min:1,max:99999999,precision:2,required:true"

爲什麼價格沒有小數點 而且在價格下還有一個隱藏的

<input type="hidden" name="price"/>

 

EasyUI的樹

對於樹的數據要求

 

完成分類樹的展示必須滿足一個條件,返回數據符合

EasyUI的樹結構;EasyUI接收的數據(controller返回的數據)都是

json

 

EasyUI對數結構的要求

每個節點可以包含以下屬性:

· id: 節點id,它是重要的來加載遠程數據

· text: 節點文本來顯示 //就是name的值

· state: 節點狀態,“open”或“closed”,默認是“open”。當設置爲“closed”,節點有子節點,並將負載從遠程站點 //如果是父節點需要返回closed,如果是子節點需要返回open;

· checked: 顯示選定的節點是否選中。

· attributes: 自定義屬性可以被添加到一個節點

· children: 一個數組節點定義了一些子節點

需要改造pojo ItemCat

 

構建數據必須體現層級關係

id和parent_id;在state的構建中體現的

頁面的數據請求分2個情況

第一次訪問,初始化訪問,parent_id如何獲取

後續的訪問,id可以獲取

 

代碼步驟

1 改造pojo ItemCat

添加getText和getState

2 mapper.xml和mapper接口

我們使用排序sql,通用mapper不支持排序

SELECT * FROM tb_item_cat WHERE parent_id=0 ORDER BY sort_order

3 service

4 controller(頁面分析)

頁面分析的步驟

前臺哪裏是發起請求的位置,利用關鍵字來查找對應的js代碼

<a href="javascript:void(0)" class="easyui-linkbutton selectItemCat">選擇類目</a>

其中只有selectItemCat可能是關鍵字

可以使用eclipse中的search功能,file

 

 // 初始化選擇類目組件

initItemCat : function(data){

            $(".selectItemCat").each(function(i,e){//i= index 下標,e:element:元素

                    var _ele = $(e);//把jquery元素轉化成js對象

    if(data && data.cid){

   _ele.after("<span style='margin-left:10px;'>"+data.cid+"</span>");

    }else{

    _ele.after("<span style='margin-left:10px;'></span>");}

    _ele.unbind('click').click(function(){//unbind解綁已經綁定到當前按鈕的click事件

   $("<div>").css({padding:"5px"}).html("<ul>")//設置窗口屬性

                            .window({

                                    width:'500',

                                height:"450",

                                modal:true,

                                closed:true,

                                iconCls:'icon-save',

                                title:'選擇類目',

 onOpen : function(){ //當窗口打開後執行

                              var _win = this;//把當前的窗口編程js對象

                                $("ul",_win).tree({

                                url:'/item/cat/list',//三元素之一

                                animate:true,//easyui的修飾

                                onClick : function(node){//初始化窗口tree後對不同節點點擊的函數調用

                                                        if($(this).tree("isLeaf",node.target)){

                                                                // 填寫到cid中

                                                                _ele.parent().find("[name=cid]").val(node.id);

                                                                _ele.next().text(node.text).attr("cid",node.id);

                                                                $(_win).window('close');

                                                                if(data && data.fun){

                                                                        data.fun.call(this,node);}}}});

            },

    onClose : function(){

                                        $(this).window("destroy");

                                }

    }).window('open');}}

 

三元素(接口文件)

請求地址'/item/cat/list'

請求參數當前節點id

controller接收時的名字能隨便寫嗎

當擴展一個封閉的節點,如果節點沒有子節點加載,它將發送節點id的值作爲http請求參數命名爲“id”到服務器上面定義通過URL檢索的子節點。

返回類型:就是查詢的List對應的json數據字符串

 

 

 

 

商品列表(分頁過程)

2018113

10:37

表設計

 

1 商品價格

不是double,double數據類型會降低數據庫執行的效率,電商

的項目以性能最最高條件設計整個架構

利用前臺js,將真實價格*100進行傳遞;

priceView 真實價格;price:計算後的價格傳遞給數據庫

2 圖片

在數據庫中,以字符串存儲,這裏的字符串是圖片的虛擬訪問路徑

最多存儲5,每張圖片的字符串以逗號分隔開

數據庫能否直接存儲圖片?

可以直接存儲圖片以大字段blog text

京淘中不能使用大字段存儲數據,大字段破壞索引

 

介紹索引:

本質上索引的存在目的是減少磁盤IO的次數

例子:查字 "李"

找到L的頁碼

找到Li的頁碼

找到李字

這裏提到的拼音法,筆畫法,偏旁部首 稱作索引

B-tree

 

索引的特點就是有序的

折半查詢

 

3 status三種正常,下架,刪除

 

商品列表的開發步驟

1 pojo

2 mapper(看情況)

SELECT * FROM tb_item ORDER BY updated

3 service

4 controller(頁面分析)

觀察item-list中是否有關於商品查詢的關鍵字

<table class="easyui-datagrid" id="itemList" title="商品列表"

       data-options="singleSelect:false,collapsible:true,pagination:true,url:'/item/query',method:'get',pageSize:20,toolbar:toolbar">

使用的EasyUI中一個組件datagrid 可以調用data-options屬性中的連接發起ajax請求

獲取請求地址後datagrid組件調用js

/item/query來尋找js調用的代碼

參數無,查詢所有的列表信息

返回值,List的對象的json

 

如果引入分頁插件,json串中有沒有分頁數據的體現

在京淘中後臺分頁調用EasyUI的組件,引入分頁jar包完成數據封裝

傳遞給EasyUI的數據需要一個固定格式

 

爲分頁做準備,不能返回給前臺List<Item>

需要EasyUIResult的對象的json字符串

 

 

商品列表的分頁

2018113

11:11

分頁插件

實現分頁的對象PageHelper,

<!-- 分頁插件:com.github.pagehelper爲PageHelper類所在包名 -->

<plugin interceptor="com.github.pagehelper.PageHelper">

<!-- 方言 -->

<property name="dialect" value="mysql" />

<!-- 該參數默認爲false -->

<!-- 設置爲true時,使用RowBounds分頁會進行count查詢,查詢數據總條數 -->

<property name="rowBoundsWithCount" value="true" />

</plugin>

方言:分頁sql語句根據不同的數據庫執行不同數據庫的分頁語句

mysql limit

爲了滿足前臺的數據需求,需要一個分頁的list對象(20條)

還需要當前tb_item表中的總數3098

本質就是執行2條sql

select * from tb_item limit 20

select count(*) from tb_item

rowBoundsWithCount是否開啓總條數查詢

 

代碼需要修改ItemController

 

 

前臺商品列表的其他功能

2018113

14:31

新增

三元素

$.post("/item/save",$("#itemAddForm").serialize(), function(data){

if(data.status == 200){

$.messager.alert('提示','新增商品成功!');

}});

js代碼中找到jquery的post提交方法

其中有3個參數

第一個參數:請求地址/item/save

第二個參數$("#itemAddForm").serialize():jquery的一個序列化方法,將一個表單內的所有提交標籤序列化成

一個模擬get的字符串 username=xiao&password=123

以這種字符串進行參數的提交

pojo發生屬性變化時(這種變化是根據需求來的)

serialize的方法自動將表單裏的所有input標籤封裝成key=value進行參數的上傳,當input標籤或者內容結構發生變化時,無需修改前臺代碼

item對象

第三個參數:回單函數,data就是controller的返回數據

需要返回的對象類型,SysReuslt的json字符串

其中status的值代表不同意義;

爲什麼要json字符串

json字符串可以被js代碼直接調用封裝成js對象

拿到三元素可以編寫代碼

 

討論

try catch語句能否加在當前service中?

saveItem方法中由於事務的引入不能添加try catch否則

事務失效;但並不帶表有事務的方法永遠不能添加try catch

 

測試點擊提交

 

修改(頁面加載數據的過程)

部分數據回顯使用js代碼調用查詢list中的展示數據

有一個部分數據還是需要到後臺查詢數據庫的

請求地址:item/update

請求參數:當前表單的序列化字符串

返回值:SysResultjsonn

 

刪除

"/item/delete"

參數:“ids” 也會被springmvc處理,Long[] ids

 

商品的增刪改查部分完成

商品詳情,ItemDesc 單獨一個表格

 

 

圖片上傳

2018113

16:26

KindEditor

EasyUI類似都是前臺的富客戶端插件(基於jquery做的)

KindEditor(KE)優勢在於處理圖文並茂的數據

EasyUI無法處理有格式的數據

 

kindeditor可以展示圖片

KE可以訪問圖片的虛擬地址http://image.jt.com/2018/1/13/126341927319264.jpg;

可以解析html文本信息

 

圖片上傳

前臺的執行過程

最多上傳5張圖片,當點擊開始上傳時,多張圖片資源將被封裝成數據對象傳遞給Controller,

將本地數據上傳到服務器

controller

1  拿到這個文件名,擴展名,判斷是否合法有效

2 判斷是否是木馬(京淘中判斷木馬的邏輯非常簡單,應該調用第三方插件進行判斷更安全)

3 生成2個路徑;

· 服務器存儲真實路徑

c://jt-upload/*****/****/**.jpg

· KE訪問的虛擬路徑

http://image.jt.com/*****/****/**.jpg

4 圖片的存放目錄計算,上傳圖片非常多,一個文件夾無法有效管理

5 圖片文件的重命名;

6 保存圖片到服務器

7返回對象PicUpdaloadResult

 private Integer error=0;,0表示無異常,1代表異常

    private String url;//返回給前臺的KE進行回顯工作

    private String width;//寬

    private String height;//高

 

重新構建一個專門的上傳Controller

三元素

http://localhost:8082/pic/upload

參數 MultipartFile類型的數據 變量名稱uploadFile

PicUploadResult

 

 

當天問題

2018113

14:27

 

1

 

 

tomcat啓動佔用的端口8081已經被佔用了

解決辦法,找到8081的端口占用進程pid 幹掉

換個端口

 

2 插入數據失敗

2018-01-13 15:29:03,554 [http-bio-8082-exec-5] [org.springframework.jdbc.support.SQLErrorCodesFactory]-[DEBUG] Looking up default SQLErrorCodes for DataSource [JDBC URL = jdbc:mysql://127.0.0.1:3306/jtdb?useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true, Username = root, partitions = 1, max (per partition) = 150, min (per partition) = 5, idle max age = 30 min, idle test period = 60 min, strategy = DEFAULT]

2018-01-13 15:29:03,561 [http-bio-8082-exec-5] [org.springframework.jdbc.support.SQLErrorCodesFactory]-[WARN] Error while extracting database product name - falling back to empty error codes

org.springframework.jdbc.support.MetaDataAccessException: Error while extracting DatabaseMetaData; nested exception is java.sql.SQLException: Connection is closed!

 

 

service的saveItem方法中初始化數據添加

 

3 沒有展示新添加的數據

排序使用updated沒有用倒序 desc

 

 ===========================================================================

========================================================================

DAY04

 

知識回顧+問題

2018115

8:55

回顧

1 商品分類樹

根據EasyUI樹來確定返回數據的結構

返回Json串中{"id":"201","text","電子書刊","state":"closed"}

2 商品列表和新增

EasyUI自定義屬性特點 data-options

參數提交:jquery的ajax的post提交$.post(參數1,參數2,參數3)

參數1:請求地址

參數3:回調函數(data) data就是SysResult的json字符串

參數2:serialize,在post提交請求體中將form當中的所有input序列化成一個模擬get請求的參數字符串

3 商品修改

回顯過程和提交過程

回顯當中使用js提取列表中的數據,對於某一個商品的回顯過程,只需要到後臺查詢部分數據(商品描述)

4 商品刪除

前臺獲取勾選的Long[] ids

5 圖片上傳

前臺使用KE(KindEditor) + flash將圖片數據從客戶端讀取進行上傳

單獨寫PicUploadController

springmvc 接收的參數類型MultipartFile

判斷後綴,判斷木馬,

生成2個路徑一個存盤路徑,一個是url前臺頁面訪問路徑

 

問題:

1 圖片上傳中爲什麼做2個路徑?

真實存盤路徑c:/jt-upload

作爲真實路徑將數據(圖片)存放到服務器的位置

url:http://image.jt.com/***/***.jpg

controller返回PicUploadResult

其中4個屬性,error,width,height,url

{"error":"0","width":"100","height":"200","url":"http://image.jt.com/***/***.jpg"}

function(data){

//校驗上傳成功和失敗

data.error;

//展示圖片的大小

data.width;data.height

//KE訪問的圖片虛擬路徑

data.url

}

 

但是目前階段KE雖然能夠拿到URL,但是無法訪問到真實的圖片展示;url找不到

 

做完存盤路徑和url的映射就可以了(nginx)

2 爲什麼京淘使用單表設計?表的關聯性能爲什麼低?

何種情況使用單表?何種情況使用關聯?

外鍵關聯性能問題:

· 數據庫需要維護外鍵的內部管理(if語句,用代碼管理)

· 涉及到外鍵的操作增刪改,需要觸發相關的操作去檢查外鍵判斷外鍵,從而不得不消耗額外資源

· 外鍵的存在會導致操作數據庫的死鎖;

 

根據不同情況採用不同的表設計邏輯

不適合使用外鍵關聯的情況

用戶量大,併發量高,數據庫極其容易成爲整個架構體系中的性能瓶頸,而且開發成本可以較高

例子:互聯網電商項目;和不考慮開發成本的國企項目;

使用外鍵關聯

用戶量少,併發量不高,數據庫性能不會成爲瓶頸,要求開發成本低

例子:傳統行業(企業內部項目,OA,CRM)

 

 

屬性注入解耦

2018115

9:32

需求

對圖片上傳中的強耦合字符串,使用屬性注入來解耦

 

Properties:自行管理properties文件,使用類加載器獲取資源

 

京淘中使用架構引入PropertyPlaceHolderConfigurer

底層還是Properties:存儲讀取文件中的數據

REPOSITORY_PATH=c:\\jt-upload

IMAGE_BASE_URL=http://image.jt.com

 

架構的PropertyPlaceHolderConfigurer:分裝了Property對象,是spring架構支持的一套API,方便在配置xml時就設置文件位置,和讀取數據的其他配置信息;

京淘中的擴展類ExtendedPropertyPlaceholderConfigurer

只擴展了父類沒有的一個方法getProperty,在代碼中可以獲取讀取的數據

 

情景分析:

擴展類已經在加載後保存了所有的properties文件中的key-value

問題:可以不可以在圖片的controller當中直接注入擴展類,調用擴展類的getProperty方法使用,獲取key-value數據

 

問題:爲什麼不在controller中直接注入使用

單獨使用擴展類對象中的數據也是耦合

 

引入僞service對象PropertyService和後處理bean

來解決這種問題;

service:不參加業務邏輯的spring加載的bean,註解使用service

利用僞service中的屬性解決編譯器檢查字符串錯誤;

spring創建僞service對象時,2個屬性沒有值;

後處理bean:將擴展類對象中的數據經過bean加載後的後處理過程,將數據傳遞給僞service;利用註解來傳遞

 

屬性注入流程圖

 

 

 

 

NGINX

2018115

10:30

 

情景分析:

如何構建一個京淘項目後臺的tomcat集羣?

兩種搭建

 

 

 

有沒有一種可能,對於客戶端來講,訪問的服務器地址不變(對於客戶端透明)

 

 

 

 

NGINX(engin x)

是一個高性能的HTTP和反向代理服務器

 

上圖展示的代理稱之爲正向代理,代理的是客戶端,對客戶端的訪問處理後交給外網服務器

 

反向代理與正向代理相反,代理的服務器的響應;

 

京淘中nginx作用

解決靜態文件的訪問,圖片回顯,將url訪問連接中

image.jt.com替換成nginx所在服務器的真實存盤路徑

c://jt-upload

nginx的動靜分離

 

負載均衡;

負載:服務器承受的訪問壓力;

均衡:物理均衡和邏輯均衡

權重:權衡訪問的重心,根據服務器性能判斷

session黏着;根據session共享來做的均衡方式

 

NGINX安裝(windows版本)

環境包中nginx1.9.9

 

啓動:在原有包中增加了3個.bat文件,作爲windows系統的啓動

停止,重啓

start啓動;

 

nginx啓動會加載配置文件,conf/nginx.conf

 

nginx的配置文件

server {//nginx啓動是加載的虛擬機單位

listen       80; //監聽的端口

server_name  manage.jt.com; //監聽的域名

 

location / { //當滿足監聽條件時,location後跟着匹配信息,

開始匹配域名和端口後的內容,

       proxy_pass http://127.0.0.1:8081; //域名和端口的替換

也就是訪問的真正服務器,直接拼接後續的訪問路徑

  

       proxy_connect_timeout 600;

       proxy_read_timeout 600;}}

根據以上內容,將manage.jt.com/page/index用nginx訪問maven啓動的tomcat

修改hosts文件,manage.jt.com需要和nginx所在服務器地址映射 127.0.0.1

 

圖片回顯:

server {

listen       80;

server_name  image.jt.com;

proxy_set_header X-Forwarded-Host $host;

proxy_set_header X-Forwarded-Server $host;

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

location / {

       root c:\\jt-upload;}}

 

補充:幾個簡單的匹配案例location

= 開頭表示精確匹配

location = /html{

匹配過程內容

}

/html/  匹配以html開頭的內容,後續繼續查詢有沒有location匹配的是/html/正則 */d

 

^~ /html/ 匹配html開頭的內容,一旦匹配上,不在搜索下面的正則匹配

/html/abc.html

 

 

 

 

 

部署linux系統的京淘

2018115

11:41

部署結構

 

使用第一種部署方式,在一臺linux服務器上配置3個tomcat實例

 

總體步驟

1 鏡像 登錄名密碼是root root

 

找到解壓文件中的vmx後綴文件

2 上傳tomcat解壓安裝

[root@bogon software]# cd /root/Desktop/

[root@bogon Desktop]# mv apache-tomcat-7.0.55.tar.gz /home/software/

 

解壓改名

[root@bogon software]# tar -xf apache-tomcat-7.0.55.tar.gz

[root@bogon software]# mv apache-tomcat-7.0.55 t1

 

3 安裝jdk(略)

 

4 複製多個tomcat實例

 

 

 

需要修改對應的tomcat文件中的配置文件的端口

t1 8080 70行左右,8009 91行左右,8005 22行

t2 8081,8019,8015

t3 8082,8029,8025

 

 

 

 

 


[root@bogon software]# vim t2/conf/server.xml

[root@bogon software]# vim t3/conf/server.xml

 

啓動tomcat

bin目錄下找到start.sh

[root@bogon bin]# ./startup.sh

配置文件 conf/server.xml

 

linux中查看啓動日誌

啓動日誌就在logs文件夾下,catalina.out

 

使用tail命令查看

 

繼續啓動t2和t3跟着查看catalina.out

 

[root@bogon logs]# tail /home/software/t2/logs/catalina.out

[root@bogon logs]# tail /home/software/t3/logs/catalina.out

5 打war包啓動

manage工程的war包導入到tomcat3個實例中,放到webaps下,ROOT.war tomcat啓動時自動解壓

war包:

 

maven工程發佈時,已經完成war的打包,將其拷貝到虛擬機使用即可

檢查tomcat進程,使用

[root@bogon logs]# ps -ef|grep tomcat

根據現實的pid使用kill命令殺掉

[root@bogon logs]# kill 5393

[root@bogon logs]# kill 5365

[root@bogon logs]# kill 5318

 

將文件修改成ROOT.war

[root@bogon ~]# cd /root/Desktop/

[root@bogon Desktop]# ls

jt-manage.war

[root@bogon Desktop]# mv jt-manage.war ROOT.war

[root@bogon Desktop]#

拷貝到t1,t2,t3的webapps中

[root@bogon Desktop]# cp ROOT.war /home/software/t1/webapps/

[root@bogon Desktop]# cp ROOT.war /home/software/t2/webapps/

[root@bogon Desktop]# cp ROOT.war /home/software/t3/webapps/

[root@bogon Desktop]#

 

啓動tocmat三個實例

使用tail檢查啓動是否成功

在虛擬機內部的瀏覽器訪問;

 

爲了可以在外部客戶端訪問虛擬機中3個tomcat,需要設置防火牆

service iptables stop 關閉所有防火牆

 

 

檢查防火牆命令

service ip tables status

 

6 實現ngnix的在3個實例中的跳轉工作

nginx中配置如下信息

upstream jt1710{ upstream 負載均衡的服務器庫,jt1710自定義名稱

server 192.168.40.170:8081 ;

server 192.168.40.170:8082 ;

server 192.168.40.180:8080 ;}

server {

listen       80;

server_name  manage.jt.com;

 

location / {

        proxy_pass http://jt1710;//

直接訪問本地tocmat變成訪問服務器庫;默認的並排方式排列的服務器就是輪詢

       proxy_connect_timeout 600;

       proxy_read_timeout 600;}}

 

修改每個tomcat實例的首頁內容區分

方便查詢負載均衡操作過程

[root@bogon ROOT]# vim /home/software/t1/webapps/ROOT/index.jsp

[root@bogon ROOT]# vim /home/software/t2/webapps/ROOT/index.jsp

[root@bogon ROOT]# vim /home/software/t3/webapps/ROOT/index.jsp

 

 

 

附錄1--nginx配置詳解

2017127

22:42

 

Nginx的配置文件nginx.conf配置詳解如下:

 

user nginx nginx ;

Nginx用戶及組:用戶 組。window下不指定

 

worker_processes 8;

工作進程:數目。根據硬件調整,通常等於CPU數量或者2倍於CPU

 

error_log  logs/error.log;  

error_log  logs/error.log  notice;  

error_log  logs/error.log  info;  

錯誤日誌:存放路徑。

 

pid logs/nginx.pid;

pid(進程標識符):存放路徑。

 

worker_rlimit_nofile 204800;

指定進程可以打開的最大描述符:數目。

這個指令是指當一個nginx進程打開的最多文件描述符數目,理論值應該是最多打開文件數(ulimit -n)與nginx進程數相除,但是nginx分配請求並不是那麼均勻,所以最好與ulimit -n 的值保持一致。

現在在linux 2.6內核下開啓文件打開數爲65535worker_rlimit_nofile就相應應該填寫65535

這是因爲nginx調度時分配請求到進程並不是那麼的均衡,所以假如填寫10240,總併發量達到3-4萬時就有進程可能超過10240了,這時會返回502錯誤。

 

events

{

use epoll;

使用epollI/O 模型。linux建議epollFreeBSD建議採用kqueuewindow下不指定。

補充說明:

apache相類,nginx針對不同的操作系統,有不同的事件模型

A)標準事件模型

Selectpoll屬於標準事件模型,如果當前系統不存在更有效的方法,nginx會選擇selectpoll

B)高效事件模型

Kqueue:使用於FreeBSD 4.1+, OpenBSD 2.9+, NetBSD 2.0  MacOS X.使用雙處理器的MacOS X系統使用kqueue可能會造成內核崩潰。

Epoll:使用於Linux內核2.6版本及以後的系統。

/dev/poll:使用於Solaris 7 11/99+HP/UX 11.22+ (eventport)IRIX 6.5.15+  Tru64 UNIX 5.1A+

Eventport:使用於Solaris 10 爲了防止出現內核崩潰的問題, 有必要安裝安全補丁。

 

worker_connections 204800;

沒個工作進程的最大連接數量。根據硬件調整,和前面工作進程配合起來用,儘量大,但是別把cpu跑到100%就行。每個進程允許的最多連接數,理論上每臺nginx服務器的最大連接數爲。worker_processes*worker_connections

keepalive_timeout 60;

keepalive超時時間。

 

client_header_buffer_size 4k;

客戶端請求頭部的緩衝區大小。這個可以根據你的系統分頁大小來設置,一般一個請求頭的大小不會超過1k,不過由於一般系統分頁都要大於1k,所以這裏設置爲分頁大小。

分頁大小可以用命令getconf PAGESIZE 取得。

[root@web001 ~]# getconf PAGESIZE

4096

但也有client_header_buffer_size超過4k的情況,但是client_header_buffer_size該值必須設置爲系統分頁大小的整倍數。

 

open_file_cache max=65535 inactive=60s;

這個將爲打開文件指定緩存,默認是沒有啓用的,max指定緩存數量,建議和打開文件數一致,inactive是指經過多長時間文件沒被請求後刪除緩存。

 

open_file_cache_valid 80s;

這個是指多長時間檢查一次緩存的有效信息。

 

open_file_cache_min_uses 1;

open_file_cache指令中的inactive參數時間內文件的最少使用次數,如果超過這個數字,文件描述符一直是在緩存中打開的,如上例,如果有一個文件在inactive時間內一次沒被使用,它將被移除。

}

 

 

##設定http服務器,利用它的反向代理功能提供負載均衡支持

http

{

include mime.types;

設定mime類型,類型由mime.type文件定義

 

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"';

log_format log404 '$status [$time_local] $remote_addr $host$request_uri $sent_http_location';

日誌格式設置。

$remote_addr$http_x_forwarded_for用以記錄客戶端的ip地址;

$remote_user:用來記錄客戶端用戶名稱;

$time_local 用來記錄訪問時間與時區;

$request 用來記錄請求的urlhttp協議;

$status 用來記錄請求狀態;成功是200

$body_bytes_sent :記錄發送給客戶端文件主體內容大小;

$http_referer:用來記錄從那個頁面鏈接訪問過來的;

$http_user_agent:記錄客戶瀏覽器的相關信息;

通常web服務器放在反向代理的後面,這樣就不能獲取到客戶的IP地址了,通過$remote_add拿到的IP地址是反向代理服務器的iP地址。反向代理服務器在轉發請求的http頭信息中,可以增加x_forwarded_for信息,用以記錄原有客戶端的IP地址和原來客戶端的請求的服務器地址。

 

access_log  logs/host.access.log  main;

access_log  logs/host.access.404.log  log404;

用了log_format指令設置了日誌格式之後,需要用access_log指令指定日誌文件的存放路徑

 

server_names_hash_bucket_size 128;

#保存服務器名字的hash表是由指令server_names_hash_max_size server_names_hash_bucket_size所控制的。參數hash bucket size總是等於hash表的大小,並且是一路處理器緩存大小的倍數。在減少了在內存中的存取次數後,使在處理器中加速查找hash表鍵值成爲可能。如果hash bucket size等於一路處理器緩存的大小,那麼在查找鍵的時候,最壞的情況下在內存中查找的次數爲2。第一次是確定存儲單元的地址,第二次是在存儲單元中查找鍵 值。因此,如果Nginx給出需要增大hash max size  hash bucket size的提示,那麼首要的是增大前一個參數的大小.

 

client_header_buffer_size 4k;

客戶端請求頭部的緩衝區大小。這個可以根據你的系統分頁大小來設置,一般一個請求的頭部大小不會超過1k,不過由於一般系統分頁都要大於1k,所以這裏設置爲分頁大小。分頁大小可以用命令getconf PAGESIZE取得。

 

large_client_header_buffers 8 128k;

客戶請求頭緩衝大小。nginx默認會用client_header_buffer_size這個buffer來讀取header值,如果

header過大,它會使用large_client_header_buffers來讀取。

 

open_file_cache max=102400 inactive=20s;

這個指令指定緩存是否啓用。

: open_file_cache max=1000 inactive=20s; 

open_file_cache_valid 30s; 

open_file_cache_min_uses 2; 

open_file_cache_errors on;

 

open_file_cache_errors

語法:open_file_cache_errors on | off 默認值:open_file_cache_errors off 使用字段:http, server, location 這個指令指定是否在搜索一個文件是記錄cache錯誤.

open_file_cache_min_uses

語法:open_file_cache_min_uses number 默認值:open_file_cache_min_uses 1 使用字段:http, server, location 這個指令指定了在open_file_cache指令無效的參數中一定的時間範圍內可以使用的最小文件數,如果使用更大的值,文件描述符在cache中總是打開狀態.

open_file_cache_valid

語法:open_file_cache_valid time 默認值:open_file_cache_valid 60 使用字段:http, server, location 這個指令指定了何時需要檢查open_file_cache中緩存項目的有效信息.

 

 

client_max_body_size 300m;

設定通過nginx上傳文件的大小

 

sendfile on;

sendfile指令指定 nginx 是否調用sendfile 函數(zero copy 方式)來輸出文件,對於普通應用,必須設爲on。如果用來進行下載等應用磁盤IO重負載應用,可設置爲off,以平衡磁盤與網絡IO處理速度,降低系統uptime

 

tcp_nopush on;

此選項允許或禁止使用sockeTCP_CORK的選項,此選項僅在使用sendfile的時候使用

 

proxy_connect_timeout 90; 

後端服務器連接的超時時間_發起握手等候響應超時時間

 

proxy_read_timeout 180;

連接成功後_等候後端服務器響應時間_其實已經進入後端的排隊之中等候處理(也可以說是後端服務器處理請求的時間)

 

proxy_send_timeout 180;

後端服務器數據回傳時間_就是在規定時間之內後端服務器必須傳完所有的數據

 

proxy_buffer_size 256k;

設置從被代理服務器讀取的第一部分應答的緩衝區大小,通常情況下這部分應答中包含一個小的應答頭,默認情況下這個值的大小爲指令proxy_buffers中指定的一個緩衝區的大小,不過可以將其設置爲更小

 

proxy_buffers 4 256k;

設置用於讀取應答(來自被代理服務器)的緩衝區數目和大小,默認情況也爲分頁大小,根據操作系統的不同可能是4k或者8k

 

proxy_busy_buffers_size 256k;

 

proxy_temp_file_write_size 256k;

設置在寫入proxy_temp_path時數據的大小,預防一個工作進程在傳遞文件時阻塞太長

 

proxy_temp_path /data0/proxy_temp_dir;

proxy_temp_pathproxy_cache_path指定的路徑必須在同一分區

 

proxy_cache_path /data0/proxy_cache_dir levels=1:2 keys_zone=cache_one:200m inactive=1d max_size=30g;

#設置內存緩存空間大小爲200MB1天沒有被訪問的內容自動清除,硬盤緩存空間大小爲30GB

keepalive_timeout 120;

keepalive超時時間。

 

tcp_nodelay on;

 

client_body_buffer_size 512k;

如果把它設置爲比較大的數值,例如256k,那麼,無論使用firefox還是IE瀏覽器,來提交任意小於256k的圖片,都很正常。如果註釋該指令,使用默認的client_body_buffer_size設置,也就是操作系統頁面大小的兩倍,8k或者16k,問題就出現了。

無論使用firefox4.0還是IE8.0,提交一個比較大,200k左右的圖片,都返回500 Internal Server Error錯誤

 

proxy_intercept_errors on;

表示使nginx阻止HTTP應答代碼爲400或者更高的應答。

 

upstream bakend {

server 127.0.0.1:8027;

server 127.0.0.1:8028;

server 127.0.0.1:8029;

hash $request_uri;

}

nginxupstream目前支持4種方式的分配

1、輪詢(默認)

每個請求按時間順序逐一分配到不同的後端服務器,如果後端服務器down掉,能自動剔除。

2weight

指定輪詢機率,weight和訪問比率成正比,用於後端服務器性能不均的情況。

例如:

upstream bakend {

server 192.168.0.14 weight=10;

server 192.168.0.15 weight=10;

}

2ip_hash

每個請求按訪問iphash結果分配,這樣每個訪客固定訪問一個後端服務器,可以解決session的問題。

例如:

upstream bakend {

ip_hash;

server 192.168.0.14:88;

server 192.168.0.15:80;

}

3fair(第三方)

按後端服務器的響應時間來分配請求,響應時間短的優先分配。

upstream backend {

server server1;

server server2;

fair;

}

4url_hash(第三方)

按訪問urlhash結果來分配請求,使每個url定向到同一個後端服務器,後端服務器爲緩存時比較有效。

例:在upstream中加入hash語句,server語句中不能寫入weight等其他的參數,hash_method是使用的hash算法

upstream backend {

server squid1:3128;

server squid2:3128;

hash $request_uri;

hash_method crc32;

}

tips:

upstream bakend{#定義負載均衡設備的Ip及設備狀態}{

ip_hash;

server 127.0.0.1:9090 down;

server 127.0.0.1:8080 weight=2;

server 127.0.0.1:6060;

server 127.0.0.1:7070 backup;

}

在需要使用負載均衡的server中增加

proxy_pass http://bakend/;

每個設備的狀態設置爲:

1.down表示單前的server暫時不參與負載

2.weightweight越大,負載的權重就越大。

3.max_fails:允許請求失敗的次數默認爲1.當超過最大次數時,返回proxy_next_upstream模塊定義的錯誤

4.fail_timeout:max_fails次失敗後,暫停的時間。

5.backup 其它所有的非backup機器down或者忙的時候,請求backup機器。所以這臺機器壓力會最輕。

nginx支持同時設置多組的負載均衡,用來給不用的server來使用。

client_body_in_file_only設置爲On 可以講client post過來的數據記錄到文件中用來做debug

client_body_temp_path設置記錄文件的目錄 可以設置最多3層目錄

locationURL進行匹配.可以進行重定向或者進行新的代理 負載均衡

 

 

##配置虛擬機

server

{

listen 80;

配置監聽端口

 

server_name image.***.com;

配置訪問域名

 

location ~* \.(mp3|exe)$ {

對以“mp3exe”結尾的地址進行負載均衡

 

proxy_pass http://img_relay$request_uri;

設置被代理服務器的端口或套接字,以及URL

 

proxy_set_header Host $host;

proxy_set_header X-Real-IP $remote_addr;

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

以上三行,目的是將代理服務器收到的用戶的信息傳到真實服務器上

}

 

location /face {

if ($http_user_agent ~* "xnp") {

rewrite ^(.*)$ http://211.151.188.190:8080/face.jpg redirect;

}

proxy_pass http://img_relay$request_uri;

proxy_set_header Host $host;

proxy_set_header X-Real-IP $remote_addr;

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

error_page 404 502 = @fetch;

}

location @fetch {

access_log /data/logs/face.log log404;

rewrite ^(.*)$ http://211.151.188.190:8080/face.jpg redirect;

}

location /image {

if ($http_user_agent ~* "xnp") {

rewrite ^(.*)$ http://211.151.188.190:8080/face.jpg redirect;

}

proxy_pass http://img_relay$request_uri;

proxy_set_header Host $host;

proxy_set_header X-Real-IP $remote_addr;

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

error_page 404 502 = @fetch;

}

location @fetch {

access_log /data/logs/image.log log404;

rewrite ^(.*)$ http://211.151.188.190:8080/face.jpg redirect;

}

}

 

##其他舉例

server

{

listen 80;

server_name *.***.com *.***.cn;

location ~* \.(mp3|exe)$ {

proxy_pass http://img_relay$request_uri;

proxy_set_header Host $host;

proxy_set_header X-Real-IP $remote_addr;

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

}

location / {

if ($http_user_agent ~* "xnp") {

rewrite ^(.*)$ http://i1.***img.com/help/noimg.gif redirect;

}

proxy_pass http://img_relay$request_uri;

proxy_set_header Host $host;

proxy_set_header X-Real-IP $remote_addr;

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

#error_page 404 http://i1.***img.com/help/noimg.gif;

error_page 404 502 = @fetch;

}

location @fetch {

access_log /data/logs/baijiaqi.log log404;

rewrite ^(.*)$ http://i1.***img.com/help/noimg.gif redirect;

}

}

server

{

listen 80;

server_name *.***img.com;

 

location ~* \.(mp3|exe)$ {

proxy_pass http://img_relay$request_uri;

proxy_set_header Host $host;

proxy_set_header X-Real-IP $remote_addr;

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

}

location / {

if ($http_user_agent ~* "xnp") {

rewrite ^(.*)$ http://i1.***img.com/help/noimg.gif;

}

proxy_pass http://img_relay$request_uri;

proxy_set_header Host $host;

proxy_set_header X-Real-IP $remote_addr;

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

#error_page 404 http://i1.***img.com/help/noimg.gif;

error_page 404 = @fetch;

}

#access_log off;

location @fetch {

access_log /data/logs/baijiaqi.log log404;

rewrite ^(.*)$ http://i1.***img.com/help/noimg.gif redirect;

}

}

server

{

listen 8080;

server_name ngx-ha.***img.com;

location / {

stub_status on;

access_log off;

}

}

server {

listen 80;

server_name imgsrc1.***.net;

root html;

}

 

server {

listen 80;

server_name ***.com w.***.com;

# access_log /usr/local/nginx/logs/access_log main;

location / {

rewrite ^(.*)$ http://www.***.com/ ;

}

}

server {

listen 80;

server_name *******.com w.*******.com;

# access_log /usr/local/nginx/logs/access_log main;

location / {

rewrite ^(.*)$ http://www.*******.com/;

}

}

server {

listen 80;

server_name ******.com;

# access_log /usr/local/nginx/logs/access_log main;

location / {

rewrite ^(.*)$ http://www.******.com/;

}

}

location /NginxStatus {

stub_status on;

access_log on;

auth_basic "NginxStatus";

auth_basic_user_file conf/htpasswd;

}

#設定查看Nginx狀態的地址

 

location ~ /\.ht {

deny all;

}

#禁止訪問.htxxx文件

}

 

註釋:變量

Ngx_http_core_module模塊支持內置變量,他們的名字和apache的內置變量是一致的。

首先是說明客戶請求title中的行,例如$http_user_agent,$http_cookie等等。

此外還有其它的一些變量

$args此變量與請求行中的參數相等

$content_length等於請求行的“Content_Length”的值。

$content_type等同與請求頭部的”Content_Type”的值

$document_root等同於當前請求的root指令指定的值

$document_uri$uri一樣

$host與請求頭部中“Host”行指定的值或是request到達的server的名字(沒有Host行)一樣

$limit_rate允許限制的連接速率

$request_method等同於requestmethod,通常是“GET”“POST”

$remote_addr客戶端ip

$remote_port客戶端port

$remote_user等同於用戶名,由ngx_http_auth_basic_module認證

$request_filename當前請求的文件的路徑名,由rootaliasURI request組合而成

$request_body_file

$request_uri含有參數的完整的初始URI

$query_string$args一樣

$sheeme http模式(http,https)盡在要求是評估例如

Rewrite ^(.+)$ $sheme://example.com$; Redirect;

$server_protocol等同於request的協議,使用“HTTP/“HTTP/

$server_addr request到達的serverip,一般獲得此變量的值的目的是進行系統調用。爲了避免系統調用,有必要在listen指令中指明ip,並使用bind參數。

$server_name請求到達的服務器名

$server_port請求到達的服務器的端口號

$uri等同於當前request中的URI,可不同於初始值,例如內部重定向時或使用index

 

 

 

附錄2--location匹配規則

2018115

12:59

 

· =開頭表示精確匹配
A 中只匹配根目錄結尾的請求,後面不能帶任何字符串。

· ^~ 匹配普通字符,不是正則匹配不能用正則表達式

· ~ 開頭表示區分大小寫的正則匹配;

· ~* 開頭表示不區分大小寫的正則匹配

· / 通用匹配, 如果沒有其它匹配,任何請求都會匹配到

 

 

location  = / {
  # 精確匹配 / ,主機名後面不能帶任何字符串
  [ configuration
 A ]
}

location  / {
  # 因爲所有的地址都以 / 開頭,所以這條規則將匹配到所有請求
  # 但是正則和最長字符串會優先匹配
  [ configuration
 B ]
}

location /documents/ {
  # 匹配任何以 /documents/ 開頭的地址,優先級比較低  [ configuration C ]
}

location ~ /documents/Abc {
  # 匹配任何以 /documents/ 開頭的地址,匹配符合以後,還要繼續往下搜索
  # 只有後面的正則表達式沒有匹配到時,這一條纔會採用這一條
  [ configuration CC ]
}

location ^~ /images/ {
  # 匹配任何以 /images/ 開頭的地址,匹配符合以後,停止往下搜索正則,採用這一條。
  [ configuration D ]
}

location ~* \.(gif|jpg|jpeg)$ {
  # 匹配所有以 gif,jpg或jpeg 結尾的請求
  # 然而,所有請求 /images/ 下的圖片會被 config D 處理,因爲 ^~ 到達不了這一條正則
  [ configuration E ]
}

location /images/ {
  # 字符匹配到 /images/,繼續往下,會發現 ^~ 存在
  [ configuration F ]
}

location ~* /js/.*/\.js

 

 

 

 

 

當前問題

2018115

15:55

1 tomcat啓動後沒法訪問manage後臺

原因:原有的ROOT下的文件和拷貝的ROOT.war衝突

解決辦法:停掉所有的tomcat

調用各自的bin下的shutdown

然後將webapps中所有文件刪除清空

[root@bogon webapps]# rm -rf /home/software/t1/webapps/*

[root@bogon webapps]# rm -rf /home/software/t2/webapps/*

[root@bogon webapps]# rm -rf /home/software/t3/webapps/*

在把ROOT.war傳入webapps中,啓動tomcat

 

2問題:在啓動tomcat發現不成功,tail日誌文件顯示尋找jdk1.7文件找不到

 

 原因:/etc/profile 默認配置的1.7

解決:配置好jdk1.8然後再每次啓動tomcat時,

source /etc/profile

 

JAVA_HOME=/home/software/jdk1.8  /不要丟

PATH=$PATH:./:$JAVA_HOME/bin

export PATH JAVA_HOME

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章