1月 20

Session处理方面的知识总结

HTTP是无状态的协议,所以每次到web的请求都是单独的连接。为了在一定时间内保存
客户的浏览记录,经常采用Cookie和Session在一段时间内来保存客户的交互数据。Cookie
比较简单。服务器在响应请求时将需要数据,以“键-值”对的形式通过响应信息保存在客户端,
当浏览器再次访问相同的应用时,客户端会将原先的Cookie通过请求信息带到服务器端,从而
保持用户的会话状态,但Cookie信息保存在客户端,存在较大的安全隐患,并且大部分浏览器
对Cookie的数目及数据大小有严格的限制(一般是4K)。为了解决Cookie的问题,可以采用
session方法。以下主要整理session方面的知识。

1.session的原理
session存放于服务器,web服务为客户端创建并、维护一个Session对象,用于存放数据。
用户打开一个浏览器访问某个应用开始,到关闭浏览器为止交互过程称为一个“会话”。会话
开始时WEB服务创建Session对象,同时服务器会为该Session产生一个唯一编号,这个编号称
之为SessionID,服务器以Cookie的方式将SessionID存放在客户端。当浏览器再次访问该服务器时,
浏览器将SessionID作为Cookie信息带到服务器,服务器可以通过该SessionID检索到Session对
象,并对其需要访问的资源进行响应。当用户关闭浏览器时客户端保存SessionID的Cookie将会被清
除。需要注意的是,Cookie中仅仅保存了一个SessionID,具体的信息由web服务来维护,所以服务
器端的内存开销也会随之增大。

2.session存放的信息
Tomcat默认的方式是使用StandardManager来管理Session。Tomcat 默认会有session.ser的文
件,存放在“Tomcat主目录workCatalina localhost应用名”路径下。tomcat启动后会读取这个文件,
载入其中的Session信息,然后把它删掉。
也可以更改Tomcat默认的Session管理方式。在“Tomcat主目录confCatalina”下建立应用对于
的Context定义,如建立名为test.xml的XML文件,文件的内容如下:

maxInactiveInterval=”60″ pathname=””/>

通过Context元素的子元素Manager配置Session的管理对象:
className属性用于指定管理Session的类可以是StandarManager或PersitentManager。
maxActiveSessions表示允许最多活动Session对象的数目,-1表示不限制。
maxInactiveInterval表示Session默认的最长不活动间隔,单位为秒。
pathname表示StandarManager在服务器重启或应用重新加载时持久化Session对象的文件名,此处设置
为“”相当于关掉了Session的持久化机制。

3.session的处理过程
在Java Web Server(即Servlet/JSP Server)中,Session ID用jsessionid表示(请参见Servlet规范)。

3.1 session请求
HTTP Request一般由3部分组成:
(1)Request Line
这一行由HTTP Method(如GET或POST)、URL、和HTTP版本号组成。
例如,GET http://www.w3.org/pub/WWW/TheProject.html HTTP/1.1
(2)Request Headers
这部分定义了一些重要的头部信息,如,浏览器的种类,语言,类型。Request Headers中还可以包括
Cookie的定义。
例如:
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; GTB6.4)
Accept-Language: en-us
Cookie: jsessionid=1001
(3)Message Body
如果HTTP Method是GET,那么Message Body为空。 如果HTTP Method是POST,说明这个HTTP Request
是submit一个HTML Form的结果, 那么Message Body为HTML Form里面定义的Input属性。例如,
user=guest
password=guest
jsessionid=aaaa
注意,如果把HTML Form元素的Method属性改为GET。那么,Message Body为空,所有的Input属性都
会加在URL的后面。你在浏览器的URL地址栏中会看到这些属性,类似于
http://www.xxxx.com/login.do?user=guest&password=aaaa&jsessionid=1111111
从理论上来说,这3个部分(Request URL,Cookie Header, Message Body)都可以用来存放Session ID。
由于Message Body方法必须需要一个包含Session ID的HTML Form,所以这种方法不通用。

3.2 URL重写
Session对象的正常使用要依赖于Cookie。如果考虑到客户端浏览器可能出于安全的考虑禁用了Cookie,应该
使用URL重写的方式使Session在客户端禁用Cookie的情况下继续生效。
首先刷新一个页面,给这个页面定义一个名字,然后写入session并链接到下一级页面,在下一级页面访问的时候
通过response的encodeURL进行处理。也就是说下一级页面是获得上一级页面的session。

4.Session对象的持久化
session一般都存放在内存中,当服务器内存问题,或者服务器宕机时session就会丢失。有两种方法,一、将
session进行集群化,tomcat支持此功能。二、将session写入文件数据库共享内存中,方便在服务恢复是重新加载。
这就是session的持久化。 在java中session数据的序列化接口(java.io.Serializable)实现。
tomcat在进行同步的时候除了sessionid还于服务名和域名相关,所以对于大型网络即时将session保存到
memcached或者内存数据库、NFS等也会取到不同的session。
如果tomcat前有负载工具也会造成获取失误,建议在负载设备上制定session的链接规则。

整理参考:
http://tech.it168.com/jd/2007-09-29/200709291005796_1.shtml
http://www.edutt.com/book-show-3B3B3B393F423A3C363B3E3D413A366B787874.html
http://virgos.javaeye.com/blog/221271

10月 17

mysql的缓存使用

张子萌[2010-10-17]

1。在配置文件中添加配置

query_cache_size = 24M
query_cache_type = 1 #0不缓存
#1 缓存所有的结果,除了 SELECT SQL_NO_CACHE … 查询
#2 仅缓存 SELECT SQL_CACHE … 查询
query_cache_limit = 1048576 #不缓存大于这个值的结果。(缺省为 1M)

2。添加完毕重启mysql数据库

3。登陆mysql数据库查看缓存设置情况

mysql > show variables like ‘%query%’;

have_query_cache 缓存是否可用
long_query_time 超过N秒才记录
query_alloc_block_size 缓存分配的块大小(推荐4096为4k)
query_cache_limit 指示每个查询结果集最大的缓存限制,超过这个值的结果集不缓存
query_cache_min_res_unit 被分配给缓存的最小的块的数量
query_prealloc_size 被缓存用于解析和执行的持久buffer的大小
query_cache_size 缓存的大小

4。查看mysql数据库缓存使用情况

mysql > show status like ‘Qcache%’;

Qcache_free_blocks 查询缓存中的空闲内存块的数目
Qcache_free_memory 查询缓存的空闲内存总数
Qcache_hits 缓存采样数数目
Qcache_inserts 被加入到缓存中的查询数目
Qcache_lowmem_prunes 因为缺少内存而被从缓存中删除的查询数目
Qcache_not_cached 没有被缓存的查询数目
Qcache_queries_in_cache 在缓存中已注册的查询数目
Qcache_total_blocks 查询缓存中的块的总数目

5。维护部分

5.1
查询缓存碎片率 Qcache_free_blocks / Qcache_total_blocks * 100%
如果查询缓存碎片率超过20%
flush query cache 整理缓存碎片

5.2
查询缓存利用率 (query_cache_size – Qcache_free_memory) / query_cache_size * 100%
如果利用率在25%以下,则是query_cache_size设置的过大。

5.3
查询缓存命中率 (Qcache_hits – Qcache_inserts) / Qcache_hits * 100%

5.4
刷新缓存状态
flush status

5.5
重启缓存服务
reset query cache

9月 17

ORACLE 重建过度占用的空间

[整理人:张子萌]
数据库的undotbs或临时空间占用过太(自动扩展造成),磁盘空间有点紧,所以先考虑重建一下环节压力。

创建新的UNDO表空间

1)创建新的undo空间
SQL> CREATE UNDO
TABLESPACE UNDOTBS2
DATAFILE ‘/u02/UNDOTBS2.dbf’ SIZE 2048M
AUTOEXTEND
ON NEXT 10M MAXSIZE UNLIMITED ;
2)切换使用新的undo空间
SQL> ALTER SYSTEM SET UNDO_TABLESPACE = UNDOTBS2;
3)删除原始的undo空间
SQL> DROP TABLESPACE UNDOTBS1 INCLUDING CONTENTS AND DATAFILES;

重建临时表空间

1)创建新的临时表空间
SQL> CREATE temporary
TABLESPACE TEMP2
TEMPFILE ‘/u02/temp2.DBF’ SIZE 512M
REUSE AUTOEXTEND
ON NEXT 1M MAXSIZE UNLIMITED;
2) 改变缺省临时表空间
SQL> ALTER DATABASE DEFAULT temporary TABLESPACE TEMP2;
3)删除原来临时表空间
SQL> DROP TABLESPACE TEMP1 INCLUDING CONTENTS AND DATAFILES;

6月 23

keepalived 实现 HA || AS

【整理人:张子萌 2010-06-23】
使用keepalived实现HA(High Availability)的架构,解决双机热备工作。

keepalived进行简单配置后即可使用。对nginx、tomcat、nfs和ssh的服务进行了测试运行正常。使用ping命令测试切换,效果也比较理想。

1。环境介绍

操作系统使用CentOS5。
使用两台服务器,两台的基础IP为192.168.1.3和192.168.1.4,使用vip地址为192.168.1.10。

2。准备工作。

keepalived官方网站http://www.keepalived.org/

下载源码后编译需要使用gcc,如果系统没有需要安装。

3。编译安装

# tar zxvf keepalived-1.1.20.tar.gz
# cd keepalived-1.1.20
# ./configure –prefix=/ –mandir=/usr/local/share/man/ –with-kernel-dir=/usr/src/kernels/2.6.18-164.el5-x86_64
# make
# make install

4。配置部分

使用!和#做为注释符号。

主机部分
# vi /etc/keepalived/keepalived.conf

! Configuration File for keepalived

global_defs {
notification_email {
simon-zzm@163.com #发送告警的邮件
}
notification_email_from keepalived@liaojie.com
smtp_server 172.0.0.1 #如果本地安装sendmail,可以填写本地IP
smtp_connect_timeout 30
router_id liaojie_devel
}

vrrp_instance VI_1 {
state BACKUP
interface eth0 #绑定vip地址的网卡
garp_master_delay 10
smtp_alert
virtual_router_id 61
priority 150 #vrrp路由竞争级别
advert_int 1
authentication {
auth_type PASS
auth_pass abcd
}
virtual_ipaddress {
192.168.1.10
192.168.1.10 label eth0:1
}
}

备机部分
配置和主机一样 priority的值不一样,主备机之间数据推荐相距50以上。

问题1
在make时报错如下:
/usr/src/kernels/2.6.9-89.0.25.EL-i686/include/linux/types.h:158: error: syntax error before “__sum16”
/usr/src/kernels/2.6.9-89.0.25.EL-i686/include/linux/types.h:158: warning: type defaults to `int’ in declaration of `__sum16′
/usr/src/kernels/2.6.9-89.0.25.EL-i686/include/linux/types.h:158: warning: data definition has no type or storage class
/usr/src/kernels/2.6.9-89.0.25.EL-i686/include/linux/types.h:159: error: syntax error before “__wsum”
/usr/src/kernels/2.6.9-89.0.25.EL-i686/include/linux/types.h:159: warning: type defaults to `int’ in declaration of `__wsum’
/usr/src/kernels/2.6.9-89.0.25.EL-i686/include/linux/types.h:159: warning: data definition has no type or storage class
make[2]: *** [check_daemon.o] 错误 1
make[2]: Leaving directory `/usr/local/src/keepalived-1.1.20/keepalived/check’
make[1]: *** [all] 错误 1
make[1]: Leaving directory `/usr/local/src/keepalived-1.1.20/keepalived’
make: *** [all] 错误 2

解决方案如下:
将types.h调用的部分注释掉
vi /usr/src/kernels/2.6.9-89.0.25.EL-i686/include/linux/types.h
到158行操作如下
#endif /* __KERNEL_STRICT_NAMES */
/*
typedef __u16 __bitwise __sum16;
typedef __u32 __bitwise __wsum;
*/

注:编译没有报错,建议编译完成将注释去掉。

5月 16

haproxy 安装 配置

[整理人:张子萌 2010-4]

一、概述

测试环境

操作系统CentOS

VIP地址:192.168.11

负载到两台web地址:192.168.1.2和192.168.1.3

WEB服务器备用地址:192.168.1.4

二、下载、安装

下载地址:http://haproxy.1wt.eu/download/1.4/src/haproxy-1.4.5.tar.gz

# tar zxvf haproxy-1.4.5.tar.gz

# cd haproxy-1.4.5

# make TARGET=linux26 PREFIX=/usr/local/haproxy

编译过程中TARGET=linux26 为系统内核版本为2.6。

# make install PREFIX=/usr/local/haproxy

# mkdir –p /usr/local/haproxy/logs

# groupadd –g650 haproxy

# useradd -u650 -g haproxy haproxy

三、配置

默认配置可以参见编译环境中examples/haproxy.cfg

本文手动编辑配置文件

# /usr/local/haproxy

# vi haproxy.cfg

global

log 127.0.0.1 local0 #使用本机的syslog来记录log

log 127.0.0.1 local1 notice

#log loghost local0 info

maxconn 4096 # ulimit-n必须是maxconn的两倍以上

chroot /usr/local/haproxy

uid haproxy

gid haproxy

daemon

nbproc 2 #设置haproxy的并发进程

pidfile /usr/local/haproxy/logs/haproxy.pid

#debug

#quiet

defaults

log global

mode http

option httplog

option httpclose #启用被动的http连接关闭

option dontlognull

option forwardfor #apache日志转发功能

option redispatch # 不会连接到宕机服务器

option nolinger #在连接关闭时立即清理连接,减少FIN_WAIT1连接

retries 3 #web无法访问的重试次数

maxconn 2000

balance roundrobin

contimeout 5000

clitimeout 50000

srvtimeout 50000

listen test 192.168.1.1:80

mode http #监听模式”tcp”也即4层,和”http”,即7层

stats enable #打开状态监控

stats auth admin:admin #进入状态监控页面

stats refresh 5s

stats uri /haproxy-stats #状态监控后缀

balance roundrobin #负载算法 roundrobin(动态加权轮循)source(加权源地址哈希)

cookie JSESSIONID prefix #处理session

option forwardfor #apache日志转发功能

option httpchk HEAD /robots.txt HTTP/1.0 #健康检测连接和协议

option forwardfor # 插入 X-Forwarded-For 头部

server web1 192.168.1.2 weight 3 minconn 100 maxconn 900 check inter 20000 fall 3

# inter 健康检测间隔 20000微妙

server web2 192.168.1.3 weight 3 minconn 100 maxconn 900 check inter 20000 fall 3

server web3 192.168.1.4 weight 3 check inter 20000 fall 3 backup

errorfile 400 /etc/haproxy/errors/400.http #根据错误号,解析错误页面

四、启动

命令在/usr/local/haproxy/sbin.

haproxy -f <配置文件> [-n 最大并发连接总数] [-N 每个侦听的最大并发数] [-d] [-D] [-q] [-V] [-c] [-p] [-s] [-l] [-dk] [-ds] [-de] [-dp] [-db] [-m <内存限制M>] [{-sf|-st} pidlist…]

-d 前台,debug模式

-D daemon模式启动

-q 安静模式,不输出信息

-V 详细模式

-c 对配置文件进行语法检查

-s 显示统计数据

-l 显示详细统计数据

&nbsp
; -dk 不使用kqueue

-ds 不使用speculative epoll

-de 不使用epoll

-dp 不使用poll

-db 禁用后台模式,程序跑在前台

-sf 程序启动后向pidlist里的进程发送FINISH信号,这个参数放在命令行的最后

-st 程序启动后向pidlist里的进程发送TERMINATE信号,这个参数放在命令行的最后但配置后,死活不会输出日志,还没找到解决方法,网上有些,但行不通:

建议第一次运行建议使用前台模式便于调试

./haproxy –f /usr/local/haproxy/haproxy.cfg –d

五、优化

a)日志部分

健康检测会产生大量日志,建议屏蔽掉。

apache不记录健康检查和监控的log

SetEnvIf Request_URI “^//robots.txt$” dontlog

CustomLog output/logs/cookie_logs/%w/cookie_log cookielog env=!dontlog

六、常见问题

a) 启动失败

使用./haproxy –f /usr/local/haproxy/haproxy.cfg –d启动系统报错如下:

Starting haproxy: [ALERT] 015/191034 (15631) : Starting proxy webfarm: cannot bind socket…on both load balancers

[ALERT] 056/103843 (1358) : Starting proxy www-balancer: cannot bind socket

解法方法:

修改# vi /etc/sysctl.conf

net.ipv4.ip_nonlocal_bind=1

保存结果,使结果生效

# sysctl –p