您的位置:首页 > 数据库 > SQL

通过VMWARE建立LVS+NGINX+TOMCAT+MYSQL+NFS架构入门

2014-09-10 10:41 549 查看
通过VMWARE建立LVS+NGINX+TOMCAT+MYSQL+NFS架构入门

一 母本虚拟机建立(别名:母本A)

1.CentOS设置开机自动启动sshd服务。

查看sshd是否启动:/etc/init.d/sshd status

查看sshd是否已是系统服务:chkconfig --list |grep sshd

使用如下命令设置sshd服务自动启动:chkconfig --level 3 sshd on

===========重点说明=========

开启ssh后,如果是内网网络,那么可能会出现通过ssh访问很慢,因为无法访问DNS服务器。

修改一下SSH的配置,关闭DNS,另外按网上的说法,连GSSAPI验证一并关掉

vi /etc/ssh/sshd_config

将UseDNS和GSSAPIAuthentication都设置为no

#GSSAPIAuthentication yes
GSSAPIAuthentication no
#UseDNS yes
UseDNS no

然后,重启SSH服务

/etc/init.d/sshd restart

===========END===========

2.关闭图形界面启动

vim /etc/inittab 文件中:

:id:5:initdefault:(默认的 run level 等级为 5,即图形界面)5 修改为 3 即可

找回网卡 eth0,虚拟机每clone一次,网卡mac地址更新,centos自动新增一个eth网卡

rm -f /etc/udev/rules.d/70-persistent-net.rules

reboot

关闭服务NetworkManager

chkconfig NetworkManager off

service NetworkManager stop

vi /etc/sysconfig/network-scripts/ifcfg-eth0

DEVICE=eth0 #网卡设备名称

ONBOOT=yes #启动时是否激活 yes|no

BOOTPROTO=static #协议类型 dhcp bootp none

IPADDR=192.168.134.136 #网络IP地址

NETMASK=255.255.255.0 #网络子网地址

GATEWAY=192.168.134.1 #网关地址

BROADCAST=192.168.134.255 #广播地址

TYPE=Ethernet #网卡类型为以太网

启动network服务

chkconfig network on

service network start

二 克隆LVS(通过 母本A 克隆)

1 服务器LVS1配置准备

找回网卡 eth0,虚拟机每clone一次,网卡mac地址更新,centos自动新增一个eth网卡,修改ip:192.168.134.136

rm -f /etc/udev/rules.d/70-persistent-net.rules

reboot

每台机器根据自己的需要修改主机名:

便于操作时识别主机

#hostname lvs1

vi /etc/hosts

127.0.0.1 lvs1.localdomain localhost

::1 lvs1.localdomain6 localhost6

vi /etc/sysconfig/network

NETWORKING=yes

NETWORKING_IPV6=no

HOSTNAME=lvs1.localdomain

2 设置虚拟机,加桥接网卡能上网

ifcofnig -a

vi /etc/sysconfig/network-scripts/ifcfg-eth1

DEVICE=eth1

ONBOOT=yes

BOOTPROTO=dhcp

TYPE=Ethernet

3 Piranha安装(LVS图形化管理工具)

Yum加速:yum install yum-fastestmirror

yum install ipvsadm modcluster piranha system-config-cluster php php-cli php-common

安装完成后,会生成最主要的几个文件分别是:/etc/sysconfig/ha/lvs.cf,/etc/init.d/piranha-gui,/etc/init.d/pulse

关掉上网桥接网卡

/etc/init.d/piranha-gui start

Piranha安装效果

测试方法:http://192.168.134.136:3636

测试方法:curl 127.0.0.1:3636

设置piranha密码

/usr/sbin/piranha-passwd

123456

4 防火墙打开80,3636端口

关闭掉selinux

#/usr/sbin/setenforce 0 立刻关闭 SELINUX

#/sbin/iptables -I INPUT -p tcp --dport 80 -j ACCEPT

#/sbin/iptables -I INPUT -p tcp --dport 3636 -j ACCEPT

#/etc/rc.d/init.d/iptables save

5 查看DNS是否已配置到nameserver,防止无法能访问网络(有时候不加也可以)

[root@localhost ~]# vi /etc/resolv.conf

nameserver 202.98.96.68

nameserver 61.139.2.69

Piranha配置:DR模式
http://192.168.134.136:3636
点击global settings,如下:

Primary server public ip:输入你公网IP。

点击redundancy,这里是配置lvs服务器的冗余,

点击virtual servers,配置Virtual IP Address跟real server:

然后将所有的配置激活。

主备LVS复制配置文件

scp /etc/sysconfig/ha/lvs.cf 192.168.134.137:/etc/sysconfig/ha/lvs.cf

/etc/init.d/piranha-gui start

/etc/init.d/pulse start

LVS安装效果

/usr/share/nginx/html/index.html 加入不同服务器标志
http://192.168.134.200
ipvsadm

热备切换

LVS服务自启动配置

chkconfig piranha-gui on

chkconfig pulse on

reboot

Piranha相关轮询配置参数讲解及效果演示

Round robin:轮转调度 轮询 (最简单的轮询)

Weighted least-connections:加权最少连接(考虑负载、服务器性能因素)

Weighted round robin:加权最少连接(考虑服务器性能因素)

Least-connection:最少连接(考虑负载因素)

Locality-Based Least-Connection Scheduling:基于局部性的最少连接(考虑负载、服务器性能因素,另考虑目的ip地址连接保持)

Locality-Based Least-Connection Scheduling (R):带复制的基于局部性的最少连接(考虑负载、服务器性能因素,另考虑目的ip地址连接保持,还考虑超负载的情况)

Destination Hash Scheduling:目的地址散列调度 (根据目标地址锁定服务器)

Source Hash Scheduling:源地址散列调度(根据源地址锁定服务器)

/etc/sysconfig/ha/lvs.cf 文件配置说明

serial_no = 26 #序号。

primary = 192.168.134.136 #指定主Director Server的真实IP地址,是相对与有备用的Director Server而言的,也就是给Director Server做HA Cluster。

service = lvs #指定双机的服务名。

backup_active = 1 #是否激活备用Director Server。“0”表示不激活,“1”表示激活。

backup = 192.168.134.137 #这里指定备用Director Server的真实IP地址,如果没有备用Director Server,可以用“0.0.0.0”代替。

heartbeat = 1 #是否开启心跳,1表示开启,0表示不开启。

heartbeat_port = 539 #指定心跳的UDP通信端口。

keepalive = 6 #心跳间隔时间,单位是秒。

deadtime = 8 #如果主Director Server在deadtime(秒)后没有响应,那么备份Director Server就会接管主Director Server的服务。

network = direct #指定LVS的工作模式,direct表示DR模式,nat表示NAT模式,tunnel表示TUNL模式。

debug_level = NONE #定义debug调试信息级别。

virtual http{ #指定虚拟服务的名称。

active = 1
#是否激活此服务。

address = 192.168.134.200 eth0:1 #虚拟服务绑定的虚拟IP以及网络设备名。

vip_nmask = 255.255.255.0

port = 80 #虚拟服务的端口。

send = "GET / HTTP/1.0\r\n\r\n" #给real server发送的验证字符串。

expect = "HTTP" #服务器正常运行时应该返回的文本应答信息,用来判断real server是否工作正常。

use_regex = 0 # expect选项中是否使用正则表达式,0表示不使用,1表示使用。

load_monitor = none #LVS中的Director Server能够使用 rup 或 ruptime 来监视各个real server的负载状态。该选项有3个可选值,rup、ruptime和none,如果选择rup,每个real server就必须运行rstatd服务。如果选择了ruptime,每个real server就必须运行 rwhod 服务。

scheduler = wlc #指定LVS的调度算法。 wlc加权最少连接

protocol = tcp #虚拟服务使用的协议类型。

timeout = 6 #real server失效后从lvs路由列表中移除失效real server所必须经过的时间,以秒为单位。

reentry = 15 #某个real server被移除后,重新加入lvs路由列表中所必须经过的时间,以秒为单位。

quiesce_server = 0 #如果此选项为1.那么当某个新的节点加入集群时,最少连接数会被重设为零,因此LVS会发送大量请求到此服务节点,造成新的节点服务阻塞,建议设置为0。

server nginx1 { #指定real server服务名。

address = 192.168.134.140 #指定real server的IP地址。

active = 1 #是否激活此real server服务。

port = 80

weight = 1 #指定此real server的权值,是个整数值,权值是相对于所有real server节点而言的,权值高的real server处理负载的性能相对较强。

}

server nginx2 {

address = 192.168.134.140

active = 1

port = 80

weight = 1

}

}

====================可能会出现的问题pulse dead but pid file exists=========

这是由于selinux规则设置问题,我比较懒直接把selinux配置文件修改,就解决了

查看SELinux状态:

1、/usr/sbin/sestatus -v ##如果SELinux status参数为enabled即为开启状态

SELinux status: enabled

2、getenforce ##也可以用这个命令检查

关闭SELinux:

1、临时关闭(不用重启机器):

setenforce 0 ##设置SELinux 成为permissive模式

##setenforce 1 设置SELinux 成为enforcing模式

2、修改配置文件需要重启机器:(我采用这种方式)

修改/etc/selinux/config 文件

将SELINUX=enforcing改为SELINUX=disabled

重启机器即可

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

三 克隆NGINX(通过 母本A 克隆)

1 找回网卡 eth0,虚拟机每clone一次,网卡mac地址更新,centos自动新增一个eth网卡,修改ip:192.168.134.140

rm -f /etc/udev/rules.d/70-persistent-net.rules

reboot

每台机器根据自己的需要修改主机名:

便于操作时识别主机

#hostname nginx1

/etc/hosts

/etc/sysconfig/network

2 设置虚拟机,加桥接网卡能上网

ifcofnig -a

vi /etc/sysconfig/network-scripts/ifcfg-eth1

DEVICE=eth1

ONBOOT=yes

BOOTPROTO=dhcp

TYPE=Ethernet

Yum加速:yum install yum-fastestmirror
http://nginx.org/en/download.html
3 添加nginx源:

wget http://nginx.org/packages/centos/6/noarch/RPMS/nginx-release-centos-6-0.el6.ngx.noarch.rpm
rpm -ivh nginx-release-centos-6-0.el6.ngx.noarch.rpm

yum install nginx

nginx的几个默认目录

1 配置所在目录:/etc/nginx/

2 PID目录:/var/run/nginx.pid

3 错误日志:/var/log/nginx/error.log

4 访问日志:/var/log/nginx/access.log

5 默认站点目录:/usr/share/nginx/html

4 防火墙打开80端口

关闭掉selinux

#/usr/sbin/setenforce 0 立刻关闭 SELINUX

#/sbin/iptables -I INPUT -p tcp --dport 80 -j ACCEPT

5 DR模式包返回伪装配置

#iptables -t nat -A PREROUTING -p tcp -d 192.168.52.213 --dport 80 -j REDIRECT

#/etc/rc.d/init.d/iptables save

============================重点说明Start=========================

如果虚ip没配置正确,或者把iptables关闭,都可以造成DR模式下访问虚IP不成功的情况(比如:可以ping通虚IP,但无法访问的情况)

可以通过命令

service iptables status

查看nat表里面的规则是不是我们的虚ip

Table: nat

Chain PREROUTING (policy ACCEPT)

num target prot opt source destination

1 REDIRECT tcp -- 0.0.0.0/0 192.168.52.213 tcp dpt:80

或者用# iptables -t nat -vnL PREROUTING --line-number 查看Chain PREROUTING

如果不是虚IP。那么就用以下进行删除

iptables -t nat -D PREROUTING 1(1为nat表的num号)

用以下命令保存

#/etc/rc.d/init.d/iptables save

最后再通过返回伪装配置进行添加虚IP。然后保存。

关于iptables的基本操作请参考:http://blog.csdn.net/johnstrive/article/details/26044861

-----------------------------------------------------------------------------------------------------------

关于nginx proxy_next_upstream导致的一个重复提交错误

一个请求被重复提交,原因是nginx代理后面挂着2个服务器,请求超时的时候(其实已经处理了),结果nigix发现超时,有把请求转给另外台服务器又做了次处理。

配置:proxy_next_upstream off

后问题解决,不过也会带来另外问题,比如发布的时候部分请求会出错等。
=============================重点说明End=========================

6 测试安装是否成功
http://192.168.134.140
curl 127.0.0.1:80

wget 127.0.0.1:80

7 启动nginx,并加入自启动服务

service nginx status

service nginx start

chkconfig nginx on

reboot

nginx 配置文件检测 nginx -t

Nginx调度策略

nginx 的upstream目前支持4种方式的分配

1、轮询(默认)

每个请求按时间顺序逐一分配到不同的后端服务器 ,如果后端服务器down掉,能自动剔除。

2、weight 指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况。 例如:

upstream bakend {

server 192.168.0.14 weight=10;

server 192.168.0.15 weight=10;

}

3、ip_hash

每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session 的问题。例如:

upstream bakend {

ip_hash;

server 192.168.0.14:88;

server 192.168.0.15:80;

}

4、fair(第三方)

按后端服务器的响应时间来分配请求,响应时间短的优先分配。

upstream backend {

server server1;

server server2;

fair;

}

5、url_hash(第三方)

按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,后端服务器为缓存时比较有效。

例:在upstream中加入hash语句,server语句中不能写入weight等其他的参数,hash_method是使用的hash算法

upstream backend {

server squid1:3128;

server squid2:3128;

hash $request_uri;

hash_method crc32;

}

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.weight 默认为1.weight越大,负载的权重就越大。

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层目录

location 对URL进行匹配.可以进行重定向或者进行新的代理 负载均衡

下面四种情况分别用http://hello.com/css/test.html 进行访问。

第一种:

location /css/ {

proxy_pass http://tomcat/;
}

会被代理到http://192.168.134.142:8080/test.html 这个url

第二种(相对于第一种,最后少一个 /)

location /css/ {

proxy_pass http://tomcat;
}

会被代理到http://192.168.134.142:8080/css/test.html 这个url

第三种:

location /css/ {

proxy_pass http://tomcat/js/;
}

会被代理到http://192.168.134.142:8080/js/test.html 这个url。



第四种情况(相对于第三种,最后少一个 / ):

location /css/ {

proxy_pass http://tomcat/js;
}

会被代理到http://192.168.134.142:8080/jstest.html 这个url



带“/”就会把 http://servername:port/path/替换掉
Nginx对URL进行匹配

语法规则: location [=|~|~*|^~] /uri/ { … }

= 开头表示精确匹配

^~ 开头表示uri以某个常规字符串开头,理解为匹配 url路径即可。nginx不对url做编码,因此请求为/static/20%/aa,可以被规则^~ /static/ /aa匹配到(注意是空格)。

~ 开头表示区分大小写的正则匹配

~* 开头表示不区分大小写的正则匹配

!~和!~*分别为区分大小写不匹配及不区分大小写不匹配 的正则

/ 通用匹配,任何请求都会匹配到。

多个location配置的情况下匹配顺序为:

首先匹配 =,其次匹配^~, 其次是按文件中顺序的正则匹配,最后是交给 / 通用匹配。当有匹配成功时候,停止匹配,按当前匹配规则处理请求。

“$”符号表示URL结尾

例子,有如下匹配规则例子:

location = / {

#规则A

proxy_pass http://tomcat/index;
}

location = /login {

#规则B

proxy_pass http://tomcat/login.jsp;
}

location ^~ /static/ {

#规则C

root /usr/share/nginx/html;

index index.html index.htm;

}

location ~ \.(gif|jpg|png|js|css)$ {

#规则D

root /usr/share/nginx/html;

}

location ~* \.png$ {

#规则E

proxy_pass http://tomcat;
}

location ~\.shtml$ {

#规则F

root /usr/share/nginx/html;

if (!-e $request_filename) {

proxy_pass http://tomcat;
}

}

location ~*\.shtml$ {

#规则G

root /usr/share/nginx/html;

if (!-e $request_filename) {

proxy_pass http://tomcat;
}

}

location / {

#规则H

proxy_pass http://tomcat;
}

访问根目录/, 比如http://hello.com/ 将匹配规则A

访问http://hello.com/login将匹配规则B,http://hello.com/register则匹配规则H

访问http://hello.com/static/a.html将匹配规则C

访问http://hello.com/a.gif,http://hello.com/b.jpg将匹配规则D和规则E,但是规则D顺序优先,规则E不起作用, 而http://hello.com/static/c.png则优先匹配到 规则C

访问http://hello.com/a.PNG则匹配规则E, 而不会匹配规则D,因为规则E不区分大小写。

访问http://hello.com/a.shtml不会匹配规则F和规则G,http://hello.com/a.SHTML不会匹配规则G,因为不区分大小写。规则F,规则G属于排除法,符合匹配规则但是不会匹配到,所以想想看实际应用中哪里会用到。

访问http://hello.com/category/id/1111则最终匹配到规则H,因为以上规则都不匹配,这个时候应该是nginx转发请求给后端应用服务器,比如FastCGI(php),tomcat(jsp),nginx作为方向代理服务器存在。

Nginx对URL进行匹配-常用

所以实际使用中,至少有三个匹配规则定义常用,如下:

直接匹配网站根,通过域名访问网站首页比较频繁,使用这个会加速处理,官网如是说。这里是直接转发给后端应用服务器了,也可以是一个静态首页

# 第一个必选规则

location = / {

proxy_pass http://tomcat/index
}

# 第二个必选规则是处理静态文件请求,这是nginx作为http服务器的强项

# 有两种配置模式,目录匹配或后缀匹配,任选其一或搭配使用

location ^~ /static/ {

root /webroot/static/;

}

location ~* \.(gif|jpg|jpeg|png|css|js|ico)$ {

root /webroot/res/;

}

#第三个规则就是通用规则,用来转发动态请求到后端应用服务器

#非静态文件请求就默认是动态请求,自己根据实际把握

#毕竟目前的一些框架的流行,带.php,.jsp后缀的情况很少了

location / {

proxy_pass http://tomcat/
}

Nginx一些可用的全局变量

$arg_PARAMETER #这个变量包含GET请求中,如果有变量PARAMETER时的值。

$args #这个变量等于请求行中(GET请求)的参数,例如foo=123&bar=blahblah;

$binary_remote_addr #二进制的客户地址。

$body_bytes_sent #响应时送出的body字节数数量。即使连接中断,这个数据也是精确的。

$content_length #请求头中的Content-length字段。

$content_type #请求头中的Content-Type字段。

$cookie_COOKIE #cookie COOKIE变量的值

$document_root #当前请求在root指令中指定的值。

$document_uri #与$uri相同。

$host #请求主机头字段,否则为服务器名称。

$is_args #如果有$args参数,这个变量等于”?”,否则等于”",空值。

$http_user_agent #客户端agent信息

$http_cookie #客户端cookie信息

$limit_rate #这个变量可以限制连接速率。

$query_string #与$args相同。

$request_body_file #客户端请求主体信息的临时文件名。

$request_method #客户端请求的动作,通常为GET或POST。

$remote_addr #客户端的IP地址。

$remote_port #客户端的端口。

$remote_user #已经经过Auth Basic Module验证的用户名。

$request_completion #如果请求结束,设置为OK. 当请求未结束或如果该请求不是请求链串的最后一个时,为空(Empty)。

$request_method #GET或POST

$request_filename #当前请求的文件路径,由root或alias指令与URI请求生成。

$request_uri #包含请求参数的原始URI,不包含主机名 如:”/foo/bar.php?arg=baz”。不能修改。

$scheme #HTTP方法(如http,https)。

$server_protocol #请求使用的协议,通常是HTTP/1.0或HTTP/1.1。

$server_addr #服务器地址,在完成一次系统调用后可以确定这个值。

$server_name #服务器名称。

$server_port #请求到达服务器的端口号。

$uri #不带请求参数的当前URI,$uri不包含主机名,如”/foo/bar.html”。该值有可能和$request_uri 不一致。$request_uri是浏览器发过来的值。该值是rewrite后的值。例如做了internal redirects后。

Nginx对URL重写

三、ReWrite语法

last – 基本上都用这个Flag。

break – 中止Rewirte,不在继续匹配

redirect – 返回临时重定向的HTTP状态302

permanent – 返回永久重定向的HTTP状态301

1、下面是可以用来判断的表达式:

-f和!-f用来判断是否存在文件

-d和!-d用来判断是否存在目录

-e和!-e用来判断是否存在文件或目录

-x和!-x用来判断文件是否可执行

2、下面是可以用作判断的全局变量

例:http://localhost:88/test1/test2/test.php

$host:localhost

$server_port:88

$request_uri:http://localhost:88/test1/test2/test.php

$document_uri:/test1/test2/test.php

$document_root:D:\nginx/html

$request_filename:D:\nginx/html/test1/test2/test.php

四、Redirect语法

server {

listen 80;

server_name start.igrow.cn;

index index.html index.php;

root html;

if ($http_host !~ “^star\.igrow\.cn$" {

rewrite ^(.*) http://star.igrow.cn$1 redirect;

}

}

七、禁止访问某个目录

location ~* \.(txt|doc)${

root /data/www/wwwroot/linuxtone/test;

deny all;

}

点开头的文件禁止访问,避免以“点”开头的文件(例如.htaccess)被其他用户访问到

location ~ /. {

deny all;

}

五、防盗链location ~* \.(gif|jpg|swf)$ {

valid_referers none blocked start.igrow.cn sta.igrow.cn;

if ($invalid_referer) {

rewrite ^/ http://$host/logo.png;
}

}

Nginx动静分离URL转发

Nginx代理后,服务端收到参数

Info.jsp 看一下nginx代理后tomcat收到的参数:

<%@ page language="java" import="java.util.*" pageEncoding="GBK"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>

<head>

<title>Server Info</title>

<meta http-equiv="pragma" content="no-cache">

<meta http-equiv="cache-control" content="no-cache">

<meta http-equiv="expires" content="0">

</head>

<body>

<%

String SERVER_NAME = request.getServerName();

String SERVER_SOFTWARE = getServletContext().getServerInfo();

String SERVER_PROTOCOL = request.getProtocol();

Integer SERVER_PORT = request.getServerPort();

String REQUEST_METHOD = request.getMethod();

String PATH_INFO = request.getPathInfo();

String PATH_TRANSLATED = request.getPathTranslated();

String SCRIPT_NAME = request.getServletPath();

String DOCUMENT_ROOT = request.getRealPath("/");

String QUERY_STRING = request.getQueryString();

String REMOTE_HOST = request.getRemoteHost();

String REMOTE_ADDR = request.getRemoteAddr();

String AUTH_TYPE = request.getAuthType();

String REMOTE_USER = request.getRemoteUser();

String CONTENT_TYPE = request.getContentType();

Integer CONTENT_LENGTH = request.getContentLength();

String HTTP_ACCEPT = request.getHeader("Accept");

String HTTP_USER_AGENT = request.getHeader("User-Agent");

String HTTP_REFERER = request.getHeader("Referer");

HashMap infoMap = new HashMap();

infoMap.put("SERVER_NAME", SERVER_NAME);

infoMap.put("SERVER_SOFTWARE", SERVER_SOFTWARE);

infoMap.put("SERVER_PROTOCOL", SERVER_PROTOCOL);

infoMap.put("SERVER_PORT", SERVER_PORT);

infoMap.put("REQUEST_METHOD", REQUEST_METHOD);

infoMap.put("PATH_INFO", PATH_INFO);

infoMap.put("PATH_TRANSLATED", PATH_TRANSLATED);

infoMap.put("SCRIPT_NAME", SCRIPT_NAME);

infoMap.put("DOCUMENT_ROOT", DOCUMENT_ROOT);

infoMap.put("QUERY_STRING", QUERY_STRING);

infoMap.put("REMOTE_HOST", REMOTE_HOST);

infoMap.put("REMOTE_ADDR", REMOTE_ADDR);

infoMap.put("AUTH_TYPE", AUTH_TYPE);

infoMap.put("REMOTE_USER", REMOTE_USER);

infoMap.put("CONTENT_TYPE", CONTENT_TYPE);

infoMap.put("CONTENT_LENGTH", CONTENT_LENGTH);

infoMap.put("HTTP_ACCEPT", HTTP_ACCEPT);

infoMap.put("HTTP_USER_AGENT", HTTP_USER_AGENT);

infoMap.put("HTTP_REFERER", HTTP_REFERER);

Iterator it = infoMap.keySet().iterator();

%>

<table border="1">

<%

while (it.hasNext()) {

Object o = it.next();

%>

<tr>

<td>

<%=o%>

<td>

<%=infoMap.get(o)%>

</td>

</tr>

<%

}

%>

</table>

</body>

</html>

Nginx对URL重写

标记:

last 相当于Apache里的[L]标记,表示完成rewrite,基本上都用这个Flag

break 终止匹配, 不再匹配后面的规则

redirect 返回302临时重定向 地址栏会显示跳转后的地址

permanent 返回301永久重定向 地址栏会显示跳转后的地址

判断文件或目录:

-f和!-f用来判断是否存在文件

-d和!-d用来判断是否存在目录

-e和!-e用来判断是否存在文件或目录

-x和!-x用来判断文件是否可执行

正则表达式语法

Nginx对URL重写

1.简单例子: rewrite "/zixun/([0-9]+)(/*).html$" /zixun/$1/ last;

“/zixun/([0-9]+)(/*).html$”为正则表达式匹配你输入的url地址,表示/zixun/任意数字,至少出现一次,/出现0次或者多次,以.html结尾

/zixun/$1/ last; 符合以上规则的url 转发到 /zixun/$1/到这个链接上,这个就是你实现要获得数据的链接了 ,last为后面的不进行匹配了

如:http://www.xx.con/zixun/56.html 会把这个请求转发到 www.xx.con/zixun/56/的servlet上获得数据

2.多目录转成参数 abc.hello.com/sort/2 => abc.hello.com/info.jsp?act=sort&name=abc&id=2

if ($host ~* (.*)\.hello\.com) {

set $sub_name $1;

rewrite ^/sort\/(\d+)\/?$ /info.jsp?act=sort&cid=$sub_name&id=$1 last;

}

3.目录对换 /123456/xxxx/ -> /xxxx.jsp?id=123456

rewrite ^/(\d+)/(.+)/ /$2.jsp?id=$1 last;

4.例如下面设定nginx在用户使用ie的使用重定向到/nginx-ie目录下:

if ($http_user_agent ~ MSIE) {

rewrite ^(.*)$ /nginx-ie/$1 break;

}

5.目录自动加“/”

if (-d $request_filename){

rewrite ^/(.*)([^/])$ http://$host/$1$2/ permanent;

}

6.禁止htaccess

location ~/\.ht {

deny all;

}

7.禁止多个目录

location ~ ^/(cron|templates)/ {

deny all;

break;

}

8.文件反盗链并设置过期时间 这里的return 412 为自定义的http状态码,默认为403,方便找出正确的盗链的请求 “rewrite ^/ http://hello.com/leech.gif;”显示一张防盗链图片
“access_log off;”不记录访问日志,减轻压力 “expires 3d”所有文件3天的浏览器缓存

location ~* ^.+\.(jpg|jpeg|gif|png|swf|rar|zip|css|js)$ {

valid_referers none blocked *.hello.com localhost;

if ($invalid_referer) {

rewrite ^/ http://hello.com/leech.gif;
return 412;

break;

}

access_log off;

root /opt/lampp/htdocs/web;

expires 3d;

break;

}

9.域名跳转

server {

listen 80;

server_name h.com;

index index.html index.htm;

root /usr/share/nginx/html;

rewrite ^/ http://www.baidu.com/;
access_log off;

}

10.多域名转向

server_name hello.com hello.net ~(.*).hello.com;

index index.html index.htm index.php;

root /usr/share/nginx/html;

if ($host ~ “hello\.net") {

rewrite ^(.*) http://hello.com/net$1 redirect;

}

11.三级域名跳转

if ($http_host ~* "^(.*)\.i\.hello\.com$") {

rewrite ^(.*) http://top.hello.com$1;
break;

}

12.域名镜向

server {

listen 80;

server_name mirror.hello.com;

index index.html index.htm;

root /usr/share/nginx/html;

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

access_log off;

}

13.某个子目录作镜向

location ^~ /test{

rewrite ^.+ http://tst.hello.com/ last;

break;

}

====nginx 简单的动静分离配置======

upstream mxpro {

ip_hash;

server 10.1.1.61:8080;

server 10.1.1.62:8080;

}

server{

listen 80;

server_name 10.1.1.64; //vip 地址

location ~* \.(action|jsp) {

proxy_pass http://mxpro;
}

location ~* \.(gif|jpg|png|js|css)$ {

root /usr/share/nginx/html/;

}

location /yyjx/ {

proxy_pass http://mxpro;
}

location / {

root /usr/share/nginx/html;

index index.html;

}

}

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

NFS共享文件系统实战

nfs安装

yum install nfs-utils rpcbind

mkdir /opt/centos6

cd /opt/centos6/

mkdir /share

cat /etc/exports

vi /etc/exports

/opt/centos6 *(rw,no_root_squash)

共享目录 所有ip都可以访问(可读写,不需要root转义也就是都是root)

chkconfig nfs on

/etc/init.d/rpcbind start

/etc/init.d/nfs start

service iptables stop

chkconfig nfs off

rpcinfo –p

Nginx1上nfs客户端安装

yum install nfs-utils rpcbind

showmount -e 192.168.134.138

mkdir /opt/centos6

mount -t nfs 192.168.134.138:/opt/centos6/ /opt/centos6/

看nfs共享效果

cd /opt/centos6/

设置开机自动挂载NFS共享目录

vi /etc/rc.local

mount -t nfs -o nolock 192.168.134.138:/opt/centos6 /opt/centos6

tomcat1上nfs客户端安装

apt-get install nfs-common

showmount -e 192.168.134.138

mkdir /opt/centos6

mount -t nfs 192.168.134.138:/opt/centos6/ /opt/centos6/

看nfs共享效果

cd /opt/centos6/

ls

设置开机自动挂载NFS共享目录

vi /etc/rc.local

mount -t nfs -o nolock 192.168.134.138:/opt/centos6 /opt/centos6

mysql主从复制安装配置

mysql安装

yum -y install mysql-server

vim /etc/my.cnf

[mysqld]

character-set-server = utf8

[mysql]

default-character-set = utf8

chkconfig --list mysqld

chkconfig mysqld on

service mysqld start

service mysqld status

mysql设置root密码

mysql -u root

mysql> use mysql

mysql> select user,host,password from mysql.user;  ← 查看用户信

mysql> update user set password=password(‘123456') where user='root';

mysql> flush privileges;

mysql> quit

Mysql遗忘密码如何重置

service mysqld stop

mysqld_safe --skip-grant-tables &

mysql -u root

mysql> use mysql

mysql> update user set password=password(‘123456') where user='root';

mysql> flush privileges;

mysql> quit

service mysqld restart

Clone生成服务器mysql2

修改ip:192.168.134.145

每台机器根据自己的需要修改主机名:

便于操作时识别主机

#hostname mysql2

/etc/hosts

/etc/sysconfig/network

修改主从配置

修改主服务器master:

#vi /etc/my.cnf

[mysqld]

log-bin=mysql-bin //[必须]启用二进制日志

server-id=144 //[必须]服务器唯一ID,默认是1,一般取IP最后一段

修改从服务器slave:

#vi /etc/my.cnf

[mysqld]

log-bin=mysql-bin //[必须]启用二进制日志

server-id=145 //[必须]服务器唯一ID,默认是1,一般取IP最后一段

在主服务器上建立帐户并授权slave

service mysqld restart

/usr/local/mysql/bin/mysql -uroot -p

GRANT REPLICATION SL***E ON *.* to ‘mysync’@‘%’ identified by ‘123456'; //一般不用root帐号,“%”表示所有客户端都可能连,只要帐号,密码正确,此处可用具体客户端IP代替,如192.168.134.145,加强安全。

登录主服务器的mysql,查询master的状态

mysql>show master status;

+------------------+----------+--------------+------------------+

| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |

+------------------+----------+--------------+------------------+

| mysql-bin.000001 | 250 | | |

+------------------+----------+--------------+------------------+

1 row in set (0.00 sec)

注:执行完此步骤后不要再操作主服务器MYSQL,防止主服务器状态值变化

配置从服务器Slave

mysql>change master to master_host='192.168.134.144',master_user=‘mysync',master_password='123456',master_log_file='mysql-bin.000001',master_log_pos=250; //注意不要断开,“250”无单引号。 Mysql>start slave; //启动从服务器复制功能

检查从服务器复制功能状态

mysql> show slave status\G

*************************** 1. row ***************************

Slave_IO_State: Waiting for master to send event

Master_Host: 192.168.134.144 //主服务器地址

Master_User: mysync //授权帐户名,尽量避免使用root

Master_Port: 3306 //数据库端口,部分版本没有此行

Connect_Retry: 60

Master_Log_File: mysql-bin.000001

Read_Master_Log_Pos: 250 //#同步读取二进制日志的位置,大于等于>=Exec_Master_Log_Pos

Relay_Log_File: mysqld-relay-bin.000002

Relay_Log_Pos: 251

Relay_Master_Log_File: mysql-bin.000001

Slave_IO_Running: Yes //此状态必须YES

Slave_SQL_Running: Yes //此状态必须YES

检查从服务器复制功能状态

Replicate_Do_DB:

Replicate_Ignore_DB:

Replicate_Do_Table:

Replicate_Ignore_Table:

Replicate_Wild_Do_Table:

Replicate_Wild_Ignore_Table:

Last_Errno: 0

Last_Error:

Skip_Counter: 0

Exec_Master_Log_Pos: 250

Relay_Log_Space: 407

Until_Condition: None

Until_Log_File:

Until_Log_Pos: 0

Master_SSL_Allowed: No

Master_SSL_CA_File:

Master_SSL_CA_Path:

Master_SSL_Cert:

Master_SSL_Cipher:

Master_SSL_Key:

Seconds_Behind_Master: 0

Master_SSL_Verify_Server_Cert: No

Last_IO_Errno: 0

Last_IO_Error:

Last_SQL_Errno: 0

Last_SQL_Error:

1 row in set (0.00 sec)

防火墙打开3306端口

关闭掉selinux

#/usr/sbin/setenforce 0 立刻关闭 SELINUX

#/sbin/iptables -I INPUT -p tcp --dport 3306 -j ACCEPT

#/etc/rc.d/init.d/iptables save

允许其他服务器访问

mysql>GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION //赋予任何主机访问数据的权限

mysql>FLUSH PRIVILEGES //修改生效

mysql>EXIT //退出MySQL服务器

主从服务器测试

主服务器Mysql,建立数据库,并在这个库中建表插入一条数据:

mysql> create database hello_db;

Query OK, 1 row affected (0.00 sec)

mysql> use hello_db;

Database changed

mysql> create table hello_tb(id int(3),name char(10));

Query OK, 0 rows affected (0.00 sec)

mysql> insert into hello_tb values(001,‘hello');

Query OK, 1 row affected (0.00 sec)

mysql> show databases;

+--------------------+

| Database |

+--------------------+

| information_schema |

| hello_db |

| mysql |

| test |

+--------------------+

4 rows in set (0.00 sec)

若主服务器有老数据的情况

停止主数据的的更新操作,并生成主数据库的备份,我们可以通过mysqldump导出数据到从数据库,当然了,你也可以直接用cp命令将数据文件复制到从数据库去

注意在导出数据之前先对主数据库进行READ LOCK,以保证数据的一致性

mysql> flush tables with read lock;

之后是mysqldump

mysqldump -h127.0.0.1 -p3306 -uroot –p123456 > /home/tom/test.sql

最好在主数据库备份完毕,恢复写操作

mysql> unlock tables;

主从复制sql:scp /home/tom/test.sql 192.168.134.145: /home/tom/test.sql

从mysql导入:

mysql -u root -p123

mysql>source /home/tom/test.sql

mysql> start slave;

利用Mysql解决memcahe持久化问题

Mysql jdbc 驱动jar包下载
http://www.mysql.com/products/connector/
Mysql测试mysqltest.jsp

<%@ page import="com.mysql.jdbc.Driver" %>

<%@ page import="java.sql.*" %>

<%

String driverName="com.mysql.jdbc.Driver";

String userName="hello";

String userPasswd="123456";

String dbName="hello_db";

String tableName="hello_tb";

//联结字符串

String url="jdbc:mysql://192.168.134.144/"+dbName+"?user="+userName+"&password="+userPasswd;

Class.forName("com.mysql.jdbc.Driver").newInstance();

Connection connection=DriverManager.getConnection(url);

Statement statement = connection.createStatement();

String sql="SELECT * FROM "+tableName;

ResultSet rs = statement.executeQuery(sql);

ResultSetMetaData rmeta = rs.getMetaData();

int numColumns=rmeta.getColumnCount();

out.print("<br>表列数:"+numColumns+"<br>");

// 输出每一个数据值

for (int i = 1;i<=numColumns;i++){

out.print(rmeta.getColumnName(i));

out.print("|");

}

out.print("<br>");

while(rs.next()) {

for (int j = 1;j<=numColumns;j++){

out.print(rs.getString(j));

out.print("|");

}

out.print("<br>");

}

out.print("数据库操作成功,恭喜你");

rs.close();

statement.close();

connection.close();

%>

为程序增加mysql用户及权限

mysql> insert into mysql.user(host,user,password) values("%","hello",password("123456"));

mysql> grant all privileges on hello_db.* to hello;

mysql> flush privileges;

为count在db中建立表进行存储

mysql> use hello_db

mysql> create table count_tb(c int);

mysql> insert into count_tb values(1);

mysql> update count_tb set c=100;

修改count.jspc.jsp

从memcached未取到数据,从db获取数据

//first 未获取到,首次使用mysql获取数据

Class.forName("com.mysql.jdbc.Driver").newInstance();

Connection connection=DriverManager.getConnection(url);

Statement statement = connection.createStatement();

String sql="SELECT c FROM "+tableName;

ResultSet rs = statement.executeQuery(sql);

rs.next();

i = rs.getLong(1);

rs.close();

statement.close();

connection.close();

//以上代码从db中获取持久化的数据

mcc.add("count", Long.valueOf(i));

long M = 1000*10;//间隔超过10秒存一次db

Object updateTime = mcc.get("updateTime");

long currentTime = System.currentTimeMillis();

if( (updateTime==null) || (currentTime-((Long)updateTime).longValue())>M ){

Class.forName("com.mysql.jdbc.Driver").newInstance();

Connection connection=DriverManager.getConnection(url);

Statement statement = connection.createStatement();

String sql="UPDATE "+tableName+" SET c="+i;

statement.execute(sql);

statement.close();

connection.close();

if(updateTime==null){

mcc.add("updateTime", Long.valueOf(currentTime));

}else{

mcc.replace("updateTime", Long.valueOf(currentTime));

}

}

Tomcat服务器安装

在Oracle网站上下载相应版本的JDK,比如jdk-8u20-linux-x64.rpm,然后使用rpm -ivh安装,

接下来编辑/etc/profile文件,在文件的最后添加以下几行

在 /etc/profile 中加入以下内容:

J***A_HOME=/usr/java/jdk1.8.0_20

PATH=$PATH:$J***A_HOME/bin

CLASSPATH=.:$J***A_HOME/lib/tools.jar:$J***A_HOME/lib/dt.jar

export J***A_HOME PATH CLASSPATH

保存文件,然后运行命令:source /etc/profile使用profile生效。

最后使用命令java -version来确定安装是否成功。

安装Tomcat8

1)先安装JDK,过程见上一篇日志CentOS安装JDK。

(1)在http://tomcat.apache.org 下载Tomcat8的tar.gz版本,

然后命令:tar -zxvf apache-tomcat-8.0.12.tar.gz 解压到/usr目录下,并将目录名改为tomcat。然后执行命令chmod 777 tomcat。

(2)cp /usr/tomcat/bin/catalina.sh /etc/init.d/tomcat。

(3)vi /etc/init.d/tomcat

(4)在第二行添加以下两行

# chkconfig: 2345 10 90

# description:tomcat service

(5)添加以下两个环境变量。

CATALINA_HOME=/usr/tomcat

J***A_HOME=/usr/java/jdk1.7.0_15

(6)保存。

(7)service tomcat start启动。

(8)在浏览器中测试:http://localhost:8080

(9)测试成功运行命令:chkconfig --add tomcat,将tomcat服务随系统启动。

(10 ) vi catalina.sh 加入优化设置,参考如下
J***A_OPTS='-server -d64 -Xms2g -Xmx5g -XX:PermSize=1g -XX:MaxPermSize=2g -XX:+AggressiveOpts -XX:+UseParallelGC -XX:+UseBiasedLocking'

安装MYSQL5.6

本文以MySQL-5.6.20 32位版本rpm格式的安装方式为例,详述MySQL的安装方式,64位的rpm版本安装方式也是如此。

(一)删除老版本的MySQL

在安装前要先确定系统是否已经安装了其他版本的MySQL,如已安装其他版本的MySQL,需先删除后再安装新版本。经本文亲测,采用如下方式删除老版本的MySQL或MySQL残留文件作为方便。

1. 执行yum命令,删除MySQL的lib库,服务文件

yum remove mysql mysql-server mysql-libs mysql-server;

2. 执行find命令,查找MySQL的残留文件,然后运行“rm -rf 文件名”删除残留的MySQL文件

find / -name mysql

(二)RPM格式安装MySQL

当前,MySQL的最新版本为:5.6.20,从官网下载MySQL的rpm安装包,解压后有如下七个文件:

MySQL-client-advanced-5.6.20-1.el6.i686.rpm   #MySQL客户端程序

MySQL-devel-advanced-5.6.20-1.el6.i686.rpm #MySQL的库和头文件

MySQL-embedded-advanced-5.6.20-1.el6.i686.rpm #MySQL的嵌入式程序

MySQL-server-advanced-5.6.20-1.el6.i686.rpm #MySQL服务端程序

MySQL-shared-advanced-5.6.20-1.el6.i686.rpm #MySQL的共享库

MySQL-shared-compat-advanced-5.6.20-1.el6.i686.rpm #RHEL兼容包

MySQL-test-advanced-5.6.20-1.el6.i686.rpm #MySQL的测试组件

一般对于开发而言,我们只需要下面三个文件就可以。

MySQL-client-advanced-5.6.20-1.el6.i686.rpm

MySQL-devel-advanced-5.6.20-1.el6.i686.rpm

MySQL-server-advanced-5.6.20-1.el6.i686.rpm



1. 在重新进行安装之前,为确保万无一失,我们还是再确认一下系统中是否有MySQL极其相关的RPM安装包。如果有,则先删除。

rpm -qa | grep -i mysql

执行完上述命令后,返回空数据,则可进行第二步。否则,执行下面的命令删除MySQL的相关包文件。

yum -y remove mysql-libs*

2. 将前面提到的三个MySQL安装文件,拷贝到服务器,然后执行下述安装命令。

rpm -ivh MySQL-server-advanced-5.6.20-1.el6.i686.rpm

rpm -ivh MySQL-devel-advanced-5.6.20-1.el6.i686.rpm

rpm -ivh MySQL-client-advanced-5.6.20-1.el6.i686.rpm

上述三个命令在执行时,只有第一个命令执行的时间稍微长些,后面两个命令运行速度很快。

3.执行下述命令,将MySQL的配置文件拷贝到/etc目录下。

cp /usr/share/mysql/my-default.cnf /etc/my.cnf

4.分别运行下述命令,初始化MySQL及设置密码。

/usr/bin/mysql_install_db  #初始化MySQL

service mysql start   #启动MySQL

cat /root/.mysql_secret #查看root账号的初始密码,会出现下述所示信息

# The random password set for the root user at Mon Aug 25 10:26:57 2014 (local time): ZFRmqNPoFH3aO5PU

mysql -uroot -pZFRmqNPoFH3aO5PU #使用root账号登陆MySQL

set password=password('123456');  #更改MySQL密码,注意;不可少

exit  #退出

mysql -uroot -p123456 #使用新密码登陆

5.配置允许远程登陆。

use mysql;

mysql> select host,user,password from user;

+-----------+------+-------------------------------------------+

| host | user | password |

+-----------+------+-------------------------------------------+

| localhost | root | *DFEB299B8A17E376E7804A115F471149953B5645 |

| chenxu | root | *6E4C48EDF3CC66BC5F6E6C0980935C8ED660EFAA |

| 127.0.0.1 | root | *6E4C48EDF3CC66BC5F6E6C0980935C8ED660EFAA |

| ::1 | root | *6E4C48EDF3CC66BC5F6E6C0980935C8ED660EFAA |

+-----------+------+-------------------------------------------+

4 rows in set (0.00 sec)

mysql> update user set password=password('aqjccmtj') where user='root';

Query OK, 3 rows affected (0.00 sec)

Rows matched: 4 Changed: 3 Warnings: 0

mysql> update user set host='%' where user='root' and host='localhost';

Query OK, 1 row affected (0.00 sec)

Rows matched: 1 Changed: 1 Warnings: 0

mysql> flush privileges;

Query OK, 0 rows affected (0.00 sec)

mysql> exit

Bye

6.设置开机启动

[root@favccxx local]# chkconfig mysql on

[root@favccxx local]# chkconfig --list | grep mysql

mysql 0:off 1:off 2:on 3:on 4:on 5:on 6:off

上面打印出来的内容中,2~5为on就是开机启动了。

7.修改/etc/my.cnf,设置MySQL的字符集,配置MySQL表明不区分大小写(默认情况下,MySQL对表名区分大小写,列名不区分大小写)。在[mysqld]下面加入如下内容:

character_set_server=utf8

character_set_client=utf8

collation-server=utf8_general_ci

lower_case_table_names=1

max_connections=1000

8.MySQL的默认文件路径

/var/lib/mysql/ #数据库目录

/usr/share/mysql #配置文件目录

/usr/bin #相关命令目录

#启动脚本

9.重启MySQL

[root@favccxx local]# service mysql restart

Shutting down MySQL.. SUCCESS!

Starting MySQL. SUCCESS!

在Linux下安装MySQL是很简单的事情,但同时也是一种很繁琐的事情,谁让Linux上的操作大多数都要靠命令来完成呢。对于初学者来言,要记住所有的命令并不是多么明智的选择,最好的方法还是将一些常用的操作记录在笔记中。

===============重点说明=============

访问MySQL慢的处理

原因之一是每次访问db,mysql就会试图去解析来访问的机器的domain name,如果这时解析不到,等一段时间会失败,数据才能被取过来

在mysqld节增加一句话,不使用DNS即可,和SSH连接慢原理一样,这种连接慢的问题一般都是服务程序设置了DNS反向解析造成的。sshd,ftpd都是如此。教训。

[mysqld]
skip-name-resolve

重启mysql

/etc/init.d/mysqld restart

LINUX下的MYSQL默认是要区分表名大小写的。

  让MYSQL不区分表名大小写的方法其实很简单:
1.用ROOT登录,修改/etc/my.cnf

  2.在[mysqld]下加入一行:lower_case_table_names=1

  3.重新启动数据库即可

===========END=====================
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: