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

布局效果

 JT项目-2_第1张图片

这里直接访问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 静态菜单

  • 新增商品
  • 查询商品
  • 规格参数
  • 3 页夹        

        

                    

        

     在静态菜单中选择一个页面将会自动填充到div 首页中

    4 新增页面

    选择按钮是一个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"

    为什么价格没有小数点 而且在价格下还有一个隐藏的

     

    EasyUI的树

    对于树的数据要求

     JT项目-2_第2张图片

    完成分类树的展示必须满足一个条件,返回数据符合

    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代码

    选择类目

    其中只有selectItemCat可能是关键字

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

     JT项目-2_第3张图片

     // 初始化选择类目组件

    initItemCat : function(data){

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

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

        if(data && data.cid){

       _ele.after(""+data.cid+"");

        }else{

        _ele.after("");}

        _ele.unbind('click').click(function(){//unbind解绑已经绑定到当前按钮的click事件

       $("

    ").css({padding:"5px"}).html("
      ")//设置窗口属性

                                  .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

      表设计

       JT项目-2_第4张图片

      1 商品价格

      不是double,double数据类型会降低数据库执行的效率,电商

      的项目以性能最最高条件设计整个架构

      利用前台js,将真实价格*100进行传递;

      priceView 真实价格;price:计算后的价格传递给数据库

      2 图片

      在数据库中,以字符串存储,这里的字符串是图片的虚拟访问路径

      最多存储5,每张图片的字符串以逗号分隔开

      数据库能否直接存储图片?

      可以直接存储图片以大字段blog text

      京淘中不能使用大字段存储数据,大字段破坏索引

       

      介绍索引:

      本质上索引的存在目的是减少磁盘IO的次数

      例子:查字 "李"

      找到L的页码

      找到Li的页码

      找到李字

      这里提到的拼音法,笔画法,偏旁部首 称作索引

      B-tree

       JT项目-2_第5张图片

      索引的特点就是有序的

      折半查询

       

      3 status三种正常,下架,删除

       

      商品列表的开发步骤

      1 pojo

      2 mapper(看情况)

      SELECT * FROM tb_item ORDER BY updated

      3 service

      4 controller(页面分析)

      观察item-list中是否有关于商品查询的关键字

             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

      需要EasyUIResult的对象的json字符串

       

       

      商品列表的分页

      2018113

      11:11

      分页插件

      实现分页的对象PageHelper,

      方言:分页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

       

      1JT项目-2_第6张图片

       

       

      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找不到

       JT项目-2_第7张图片

      做完存盘路径和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;利用注解来传递

       

      属性注入流程图

       

       

       JT项目-2_第8张图片

       

      NGINX

      2018115

      10:30

       

      情景分析:

      如何构建一个京淘项目后台的tomcat集群?

      两种搭建

       JT项目-2_第9张图片

       

       

      有没有一种可能,对于客户端来讲,访问的服务器地址不变(对于客户端透明)

       JT项目-2_第10张图片

       

       

       

      NGINX(engin x)

      是一个高性能的HTTP和反向代理服务器

       JT项目-2_第11张图片

      上图展示的代理称之为正向代理,代理的是客户端,对客户端的访问处理后交给外网服务器

       JT项目-2_第12张图片

      反向代理与正向代理相反,代理的服务器的响应;

       

      京淘中nginx作用

      解决静态文件的访问,图片回显,将url访问连接中

      image.jt.com替换成nginx所在服务器的真实存盘路径

      c://jt-upload

      nginx的动静分离

       

      负载均衡;

      负载:服务器承受的访问压力;

      均衡:物理均衡和逻辑均衡

      权重:权衡访问的重心,根据服务器性能判断

      session黏着;根据session共享来做的均衡方式

       

      NGINX安装(windows版本)

      环境包中nginx1.9.9

       JT项目-2_第13张图片

      启动:在原有包中增加了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

      部署结构

      JT项目-2_第14张图片

       

      使用第一种部署方式,在一台linux服务器上配置3个tomcat实例

       

      总体步骤

      1 镜像 登录名密码是root root

       JT项目-2_第15张图片

      找到解压文件中的vmx后缀文件

      2 上传tomcat解压安装

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

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

       JT项目-2_第16张图片

      解压改名

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

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

       

      3 安装jdk(略)

       JT项目-2_第17张图片

      4 复制多个tomcat实例

       

       

       

      需要修改对应的tomcat文件中的配置文件的端口

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

      t2 8081,8019,8015

      t3 8082,8029,8025

       

       

       JT项目-2_第18张图片

       

       


      [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

       JT项目-2_第19张图片

      linux中查看启动日志

      启动日志就在logs文件夹下,catalina.out

       JT项目-2_第20张图片

      使用tail命令查看

       JT项目-2_第21张图片

      继续启动t2和t3跟着查看catalina.out

       JT项目-2_第22张图片

      [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包:

       JT项目-2_第23张图片

      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

       JT项目-2_第24张图片

      将文件修改成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 关闭所有防火墙

       

       JT项目-2_第25张图片

      检查防火墙命令

      service ip tables status

       JT项目-2_第26张图片

      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

       

       

      你可能感兴趣的:(项目)