??xml version="1.0" encoding="utf-8" standalone="yes"?>
]]>
CLOSE_WAIT状态的生成原因
首先我们知道Q如果我们的服务器程序APACHE处于CLOSE_WAIT状态的话,说明套接字是被动关闭的!
因ؓ如果是CLIENT端主动断掉当前连接的话,那么双方关闭q个TCPq接共需要四个packetQ?br />
Client ---> FIN ---> Server
Client <--- ACK <--- Server
q时候Client端处于FIN_WAIT_2状态;而Server E序处于CLOSE_WAIT状态?br />
Client <--- FIN <--- Server
q时Server 发送FINlClientQServer q为LAST_ACK状态?br />
Client ---> ACK ---> Server
Client回应了ACKQ那么Server 的套接字才会真正|ؓCLOSED状态?br />
Server E序处于CLOSE_WAIT状态,而不是LAST_ACK状态,说明q没有发FINlClientQ那么可能是在关闭连接之前还有许多数据要发送或者其他事要做Q导致没有发q个FIN packet?br />
通常来说Q一?span class="hilite3">CLOSE_WAIT会维持至?个小时的旉。如果有个流氓特地写了个E序Q给你造成一堆的CLOSE_WAITQ消?br />
你的资源Q那么通常是等不到释放那一刻,pȝ已l解军_溃了?br />
只能通过修改一下TCP/IP的参敎ͼ来羃短这个时_修改tcp_keepalive_*pd参数有助于解册个问题?br />
proc/sys/net/ipv4/下各的意义
/proc/sys/net/ipv4/icmp_timeexceed_rate
q个在traceroute时导致著名的“Solaris middle star”。这个文件控制发送ICMP Time Exceeded消息的比率?br />/proc/sys/net/ipv4/igmp_max_memberships
L上最多有多少个igmp (多播)套接字进行监听?br />/proc/sys/net/ipv4/inet_peer_gc_maxtime
求 助: Add a little explanation about the inet peer storage? Minimum interval between garbage collection passes. This interval is in effect under low (or absent) memory pressure on the pool. Measured in jiffies.
/proc/sys/net/ipv4/inet_peer_gc_mintime
每一遍碎片收集之间的最时间间隔。当内存压力比较大的时候,调整q个间隔很有效。以jiffies计?br />/proc/sys/net/ipv4/inet_peer_maxttl
entries的最大生存期。在pool没有内存压力的情况下(比如Qpool中entries的数量很的时?Q未使用的entriesl过一D|间就会过期。以jiffies计?br />/proc/sys/net/ipv4/inet_peer_minttl
entries的最生存期。应该不于汇聚端分片的生存期。当pool的大不大于inet_peer_thresholdӞq个最生存期必须予以保证。以jiffies计?br />/proc/sys/net/ipv4/inet_peer_threshold
The approximate size of the INET peer storage. Starting from this threshold entries will be thrown aggressively. This threshold also determines entries' time-to-live and time intervals between garbage collection passes. More entries, less time-to-live, less GC interval.
/proc/sys/net/ipv4/ip_autoconfig
q个文g里面写着一个数字,表示L是否通过RARP、BOOTP、DHCP或者其它机制取得其IP配置。否则就??br />/proc/sys/net/ipv4/ip_default_ttl
数据包的生存期。设|ؓ64是安全的。如果你的网l规模巨大就提高q个倹{不要因为好玩而这么做——那样会产生有害的\q路。实际上Q在很多情况下你要考虑能否减小q个倹{?br />/proc/sys/net/ipv4/ip_dynaddr/proc/sys/net/ipv4/icmp_destunreach_rate
如果你有一个动态地址的自动拨h口,得讄它。当你的自动拨号接口Ȁzȝ时候,本地所有没有收到答复的TCP套接字会重新l定到正的地址上。这可以解决引发拨号的套接字本n无法工作Q重试一ơ却可以的问题?br />/proc/sys/net/ipv4/ip_forward
内核是否转发数据包。缺省禁止?br />/proc/sys/net/ipv4/ip_local_port_range
用于向外q接的端口范围。缺省情况下其实很小Q?024?999?br />/proc/sys/net/ipv4/ip_no_pmtu_disc
如果你想止“沿途MTU发现”就讄它。“沿途MTU发现”是一U技术,可以在传输\径上出最大可能的MTU倹{参见Cookbook一章中关于“沿途MTU发现”的内容?br />/proc/sys/net/ipv4/ipfrag_high_thresh
用 于
IP分片汇聚的最大内存用量。分配了q么多字节的内存后,一旦用,分片处理E序׃丢弃分片?
When ipfrag_high_thresh bytes of memory is allocated for this purpose, the fragment handler will toss packets until ipfrag_low_thresh is reached.
/proc/sys/net/ipv4/ip_nonlocal_bind
如果你希望你的应用程序能够绑定到不属于本地网卡的地址上时Q设|这个选项。如果你的机器没有专U连?甚至是动态连?旉常有用,即你的q接断开Q你的服务也可以启动q绑定在一个指定的地址上?br />/proc/sys/net/ipv4/ipfrag_low_thresh
用于IP分片汇聚的最内存用量?br />/proc/sys/net/ipv4/ipfrag_time
IP分片在内存中的保留时?U数)?br />/proc/sys/net/ipv4/tcp_abort_on_overflow
一个布类型的标志Q控制着当有很多的连接请求时内核的行为。启用的话,如果服务蝲Q内核将d地发送RST包?br />/proc/sys/net/ipv4/tcp_fin_timeout
如 果
套接字由本端要求关闭Q这个参数决定了它保持在FIN-WAIT-2状态的旉。对端可以出错ƈ永远不关闭连接,甚至意外当机。缺省值是60U?
2.2 内核的通常值是180U,你可以按q个讄Q但要记住的是,即你的机器是一个轻载的WEB服务器,也有因ؓ大量的死套接字而内存溢出的?
险,FIN- WAIT-2的危险性比FIN-WAIT-1要小Q因为它最多只能吃?.5K内存Q但是它们的生存期长些。参?
tcp_max_orphans?br />
/proc/sys/net/ipv4/tcp_keepalive_time
当keepaliveL的时候,TCP发送keepalive消息的频度。缺省是2时?br />/proc/sys/net/ipv4/tcp_keepalive_intvl
当探没有确认时Q重新发送探的频度。缺省是75U?br />/proc/sys/net/ipv4/tcp_keepalive_probes
在认定连接失效之前,发送多个TCP的keepalive探测包。缺省值是9。这个g以tcp_keepalive_intvl之后军_了,一个连接发送了keepalive之后可以有多时间没有回应?br />/proc/sys/net/ipv4/tcp_max_orphans
p 统
中最多有多少个TCP套接字不被关联到M一个用h件句柄上。如果超q这个数字,孤儿q接即刻被复位q打印出警告信息。这个限制仅仅是Z防止单的
DoSdQ你l对不能q分依靠它或者h为地减小q个|更应该增加这个?如果增加了内存之??
This limit exists only to prevent simple DoS attacks, you _must_ not rely on this or lower the limit artificially, but rather increase it (probably, after increasing installed memory), if network conditions require more than default value, and tune network services to linger and kill such states more aggressively. ?
我再ơ提醒你Q每个孤儿套接字最多能够吃掉你64K不可交换的内存?br />/proc/sys/net/ipv4/tcp_orphan_retries
本端试图关闭TCPq接之前重试多少ơ。缺省值是7Q相当于50U~16分钟(取决于RTO)。如果你的机器是一个重载的WEB服务器,你应该考虑减低q个|因ؓq样的套接字会消耗很多重要的资源。参见tcp_max_orphans?br />/proc/sys/net/ipv4/tcp_max_syn_backlog
變W录
的那些尚未收到客L认信息的连接请求的最大倹{对于有128M内存的系l而言Q缺省值是1024Q小内存的系l则?28。如果服务器不堪重负Q?
试 试提高q个倹{注意!如果你设|这个值大?024Q最好同时调整include/net/tcp.h中的TCP_SYNQ_HSIZEQ以?
证 TCP_SYNQ_HSIZE*16 ≤tcp_max_syn_backloQ然后重新编译内核?br />/proc/sys/net/ipv4/tcp_max_tw_buckets
p 统
同时保持timewait套接字的最大数量。如果超q这个数字,time-wait套接字将立刻被清除ƈ打印警告信息。这个限制仅仅是Z防止?
的 DoSdQ你l对不能q分依靠它或者h为地减小q个|如果|络实际需要大于缺省|更应该增加这个?如果增加了内存之??br />/proc/sys/net/ipv4/tcp_retrans_collapse
为兼Ҏ些糟p的打印|的“将错就错”选项。再ơ发送时Q把数据包增大一些,来避免某些TCP协议栈的BUG?br />
/proc/sys/net/ipv4/tcp_retries1
在认定出错ƈ向网l层提交错误报告之前Q重试多次。缺省设|ؓRFC规定的最|3Q相当于3U~8分钟Q取决于RIOQ?br />/proc/sys/net/ipv4/tcp_retries2
在杀M个活动的TCPq接之前重试多少ơ。RFC 1122规定q个限制应该长于100U。这个值太了。缺省值是15Q相当于13~30分钟Q取决于RIOQ?br />/proc/sys/net/ipv4/tcp_rfc1337
q个开兛_以启动对于在RFC1337中描q的“tcp的time-wait暗杀危机”问题的修复。启用后Q内核将丢弃那些发往time-wait状态TCP套接字的RST包。却省ؓ0?br />/proc/sys/net/ipv4/tcp_sack
特别针对丢失的数据包使用选择性ACKQ这h助于快速恢复?br />/proc/sys/net/ipv4/tcp_stdurg
使用TCP紧急指针的L需求解释。因为绝大多C机采用BSD解释Q所以如果你在Linux上打开它,可能会媄响它与其它机器的正常通讯。缺省是FALSE?br />/proc/sys/net/ipv4/tcp_syn_retries
在内核放弃徏立连接之前发送SYN包的数量?br />/proc/sys/net/ipv4/tcp_synack_retries
Z打开对端的连接,内核需要发送一个SYNq带一个回应前面一个SYN的ACK。也是所谓三ơ握手中的第二次握手。这个设|决定了内核攑ּq接之前发送SYN+ACK包的数量?br />/proc/sys/net/ipv4/tcp_timestamps
旉戛_以避免序列号的卷l。一?Gbps的链路肯定会遇到以前用过的序列号。时间戳能够让内核接受这U“异常”的数据包?br />/proc/sys/net/ipv4/tcp_tw_recycle
能够更快地回收TIME-WAIT套接字。缺省值是1。除非有技术专家的和要求,否则不应修改?br />/proc/sys/net/ipv4/tcp_window_scaling
一般来说TCP/IP允许H口寸辑ֈ65535字节。对于速度实很高的网l而言q个值可能还是太。这个选项允许讄上G字节的窗口大,有利于在带宽*延迟很大的环境中使用?br />一旦内核认为它无法发包Q就会丢弃这个包Qƈ向发包的L发送ICMP通知?br />/proc/sys/net/ipv4/icmp_echo_ignore_all
Ҏ不要响应echo包。请不要讄为缺省,它可能在你正被利用成为DoSd的蟩板时可能有用?br />/proc/sys/net/ipv4/icmp_echo_ignore_broadcasts [Useful]
如果你ping子网的子|地址Q所有的机器都应该予以回应。这可能成ؓ非常好用的拒l服务攻d兗设|ؓ1来忽略这些子|广播消息?br />/proc/sys/net/ipv4/icmp_echoreply_rate
讄了向LL回应echoh的比率?br />/proc/sys/net/ipv4/icmp_ignore_bogus_error_responses
讄它之后,可以忽略ql中的那些声U回应地址是广播地址的主机生成的ICMP错误?br />/proc/sys/net/ipv4/icmp_paramprob_rate
一个相对不很明的ICMP消息Q用来回应IP头或TCP头损坏的异常数据包。你可以通过q个文g控制消息的发送比率?br />
================================================================
http://skylove.study-area.org/blog/2006/07/linuxip_29.html
tcp_syn_retries QINTEGER
默认值是5
?
于一个新接,内核要发送多个 SYN q接h才决定放弃。不应该大于255Q默认值是5Q对应于180U左x间?对于大负载而物理通信良好?
|络而言,q个值偏?可修改ؓ2.q个g仅是针对对外的连?对进来的q接,是由tcp_retries1 军_?
tcp_synack_retries QINTEGER
默认值是5
?
于远端的q接hSYNQ内怼发送SYN Q ACK数据报,以确认收C一个 SYNq接h包。这是所谓的三次握手
( threeway handshake)机制的第二个步骤。这里决定内核在攑ּq接之前所送出的 SYN+ACK 数目。不应该大于255Q默认值是
5Q对应于180U左x间?可以Ҏ上面的 tcp_syn_retries 来决定这个?
tcp_keepalive_time QINTEGER
默认值是7200(2时)
?
keepalive打开的情况下QTCP发送keepalive消息的频率?׃目前|络d{因?造成了利用这个进行的d很频J?曄也有cu?
朋友提到q?说如?边徏立了q接,然后不发送Q何数据或者rst/fin消息,那么持箋的时间是不是是2时,I接攻
? tcp_keepalive_time是预防此情形的.我个人在做nat服务的时候的修改gؓ1800U?
tcp_keepalive_probesQINTEGER
默认值是9
TCP发送keepalive探测以确定该q接已经断开的次数?注意:保持q接仅在SO_KEEPALIVE套接字选项被打开是才发?ơ数默认不需要修?当然Ҏ情Ş也可以适当地羃短此?讄?比较合?
tcp_keepalive_intvlQINTEGER
默认gؓ75
?
消息发送的频率Q乘以tcp_keepalive_probes得到对于从开始探以来没有响应的q接杀除的旉。默认gؓ75U,也就是没有活动的
q接在大约11分钟以后被丢弃?对于普通应用来?q个值有一些偏?可以Ҏ需要改?特别是webcL务器需要改该?15是个比较合适的
?
tcp_retries1 QINTEGER
默认值是3
攑ּ回应一个TCPq接h前﹐需要进行多次重试。RFC 规定最低的数值是3H这也是默认|ҎRTO的值大U在3U? 8分钟之间?注意:q个值同时还军_q入的synq接)
tcp_retries2 QINTEGER
默认gؓ15
在丢弃激z?已徏立通讯状况)的TCPq接之前H需要进行多次重试。默认gؓ15Q根据RTO的值来军_Q相当于13-30分钟(RFC1122规定Q必d?00U?.(q个值根据目前的|络讄,可以适当地改?我的|络内修改ؓ?)
tcp_orphan_retries QINTEGER
默认值是7
在近端丢弃TCPq接之前H要q行多少ơ重试。默认值是7个﹐相当于?0U? 16分钟H视 RTO 而定。如果您的系l是负蝲很大的web服务器﹐那么也许需要降低该|q类 sockets 可能会耗费大量的资源。另外参的考 tcp_max_orphans ?事实上做NAT的时?降低该g是好处显著的,我本人的|络环境中降低该gؓ3)
tcp_fin_timeout QINTEGER
默认值是 60
对于本端断开?span class="hilite1">socketq?
接,TCP保持在FIN-WAIT-2状态的旉。对方可能会断开q接或一直不l束q接或不可预料的q程M。默认gؓ 60 U。过d2.2版本的内
怸是?80 U。您可以讄该|但需要注意﹐如果您的机器载很重的web服务器﹐您可能要冒内存被大量无效数据报填满的风险HFIN-
WAIT-2 sockets 的危险性低于 FIN-WAIT-1 H因为它们最多只吃?.5K 的内存﹐但是它们存在旉更长。另外参考 tcp_max_orphans?事实上做NAT的时?降低该g是好处显著的,我本人的|络环境中降低该gؓ30)
tcp_max_tw_buckets QINTEGER
默认值是180000
p 统在同时所处理的最大 timewait sockets 数目。如果超q此数的话﹐time-wait socket 会被立即砍除q且昄警告信息。之所以要讑֮q个限制H纯_ؓ了抵御那些简单的 DoS dH千万不要h为的降低q个限制H不q﹐如果|络条g需要比默认值更多﹐则可以提高它(或许q要增加内存)?事实上做NAT的时候最好可以适当地增加该?
tcp_tw_recycle QBOOLEAN
默认值是0
打开快速 TIME-WAIT sockets 回收。除非得到技术专家的或要求﹐请不要随意修改这个倹{?做NAT的时候,打开?
tcp_tw_reuseQBOOLEAN
默认值是0
该文件表C是否允讔R新应用处于TIME-WAIT状态的socket用于新的TCPq接(q个对快速重启动某些服务,而启动后提示端口已经被用的情Ş非常有帮?
tcp_max_orphans QINTEGER
~省值是8192
pȝ所能处理不属于Mq程的TCP sockets
最大数量。假如超q这个数量﹐那么不属于Q何进E的q接会被立即resetQƈ同时昄警告信息。之所以要讑֮q个限制H纯_ؓ了抵御那些简?
的 DoS dH千万不要依赖这个或是h为的降低q个限制(q个值Redhat AS版本中设|ؓ32768,但是很多防火墙修改的时?该g?
?000)
tcp_abort_on_overflow QBOOLEAN
~省值是0
当守护进E太忙而不能接受新的连
接,pҎ发送reset消息Q默认值是false。这意味着当溢出的原因是因Z个偶然的猝发Q那么连接将恢复状态。只有在你确信守护进E真的不能完
成连接请求时才打开该选项Q该选项会媄响客L使用?对待已经满蝲的sendmail,apacheq类服务的时?q个可以很快让客Ll止q接,?
以给予服务程序处理已有连接的~冲Z,所以很多防火墙上推荐打开?
tcp_syncookies QBOOLEAN
默认值是0
只有在内核编译时选择了CONFIG_SYNCOOKIES时才会发生作用。当出现syn{候队列出现溢出时象对方发送syncookies。目的是Z防止syn floodd?br />注意Q该选项千万不能用于那些没有收到d的高负蝲服务器,如果在日志中出现synflood消息Q但是调查发现没有收到synflooddQ而是合法用户的连接负载过高的原因Q你应该调整其它参数来提高服务器性能。参?
tcp_max_syn_backlog
tcp_synack_retries
tcp_abort_on_overflow
syncookie
严重的违背TCP协议Q不允许使用TCP扩展Q可能对某些服务D严重的性能影响(如SMTP转发)?注意,该实CBSD上面使用?
tcp proxy一?是违反了RFC中关于tcpq接的三ơ握手实现的,但是对于防Msyn-flood的确很有?)
tcp_stdurg QBOOLEAN
默认gؓ0
使用 TCP urg pointer 字段中的Lh解释功能。大部䆾的主机都使用老旧的 BSD解释Q因此如果您在 Linux 打开它﹐或会D不能和它们正沟通?br />
tcp_max_syn_backlog QINTEGER
?
于那些依然还未获得客L认的连接请求﹐需要保存在队列中最大数目。对于超q?28Mb 内存的系l﹐默认值是 1024 H低于?28Mb 的则
为?28。如果服务器l常出现q蝲H可以尝试增加这个数字。警告﹗假如您将此D为大于?024H最好修改 include/net/tcp.h ?
面的 TCP_SYNQ_HSIZE H以保持 TCP_SYNQ_HSIZE*16<=tcp_max_syn_backlog Hƈ且编q核?
之内?SYN Floodd利用TCP协议散布握手的缺P伪造虚假源IP地址发送大量TCP-SYN半打开q接到目标系l,最l导致目标系l?span class="hilite1">Socket?
列资源耗 尽而无法接受新的连接。ؓ了应付这U攻击,CUnixpȝ中普遍采用多q接队列处理的方式来~冲(而不是解?q种dQ是用一个基本队列处
理正常的完 全q接应用(Connect()和Accept() )Q是用另一个队列单独存攑֍打开q接。这U双队列处理方式和其他一些系l内核措??
如Syn-Cookies/Caches)联合应用Ӟ能够比较有效的缓解小规模的SYN Floodd(事实证明<1000p/s)加大SYN
队列长度可以容纳更多{待q接的网l连接数Q所以对Server来说可以考虑增大该?)
tcp_window_scaling QINTEGER
~省gؓ1
该 文
件表C|tcp/ip会话的滑动窗口大是否可变。参数gؓ布尔|?时表C可变,?时表CZ可变。tcp/ip通常使用的窗口最大可?
刊W?5535 字节Q对于高速网l,该值可能太,q时候如果启用了该功能,可以使tcp/ip滑动H口大小增大C数量U,从而提高数据传输的能力
(RFC 1323)。(Ҏ通地百M|络而言Q关闭会降低开销Q所以如果不是高速网l,可以考虑讄?Q?br />
tcp_timestamps QBOOLEAN
~省gؓ1
Timestamps ?
在其它一些东西中H可以防范那些伪造的 sequence L。一?G的宽带线路或怼重遇到带 out-of-line数值的?
sequence L(假如它是׃上次产生?。Timestamp 会让它知道这是个 '旧封??该文件表C是否启用以一U比时重发更精的
ҎQRFC 1323Q来启用对 RTT 的计;Z实现更好的性能应该启用q个选项?
tcp_sack QBOOLEAN
~省gؓ1
使 用 Selective ACKH?
它可以用来查扄定的遗失的数据报--- 因此有助于快速恢复状态。该文g表示是否启用有选择的应{?
QSelective AcknowledgmentQ,q可以通过有选择地应{ؕ序接收到的报文来提高性能Q这样可以让发送者只发送丢q报文
D)?对于q域|通信来说q个选项应该启用Q但是这会增加对 CPU 的占用?
tcp_fack QBOOLEAN
~省gؓ1
打开FACK拥塞避免和快速重传功能?注意Q当tcp_sack讄?的时候,q个值即使设|ؓ1也无?
tcp_dsack QBOOLEAN
~省gؓ1
允许TCP发?两个完全相同"的SACK?br />
tcp_ecn QBOOLEAN
~省gؓ0
打开TCP的直接拥塞通告功能?br />
tcp_reordering QINTEGER
默认值是3
TCP中重排序的数据报最大数量 。?一般有看到推荐把这个数值略微调整大一?比如5)
tcp_retrans_collapse QBOOLEAN
~省gؓ1
对于某些有bug的打印机提供针对其bug的兼Ҏ?一般不需要这个支?可以关闭?
tcp_wmem(3个INTEGER变量)Q min, default, max
minQؓTCP socket预留用于发送缓冲的内存最倹{每个tcp socket都可以在以后都可以用它。默认gؓ4096(4K)?br />
defaultQؓTCP socket预留用于发送缓冲的内存数量Q默认情况下该g影响其它协议使用的net.core.wmem_default |一般要低于net.core.wmem_default的倹{默认gؓ16384(16K)?br />
max: 用于TCP socket?
送缓冲的内存最大倹{该g会媄响net.core.wmem_maxQ?静?选择参数SO_SNDBUF则不受该值媄响。默认gؓ
131072(128K)。(对于服务器而言Q增加这个参数的值对于发送数据很有帮?在我的网l环境中,修改Z
51200 131072 204800Q?br />
tcp_rmem (3个INTEGER变量)Q min, default, max
minQؓTCP socket预留用于接收~冲的内存数量,即在内存出现紧张情况下tcp socket都至会有这么多数量的内存用于接收缓Ԍ默认gؓ8K?br />
defaultQؓTCP socket?
留用于接收缓冲的内存数量Q默认情况下该值媄响其它协议用的 net.core.wmem_default 倹{该值决定了?
tcp_adv_win_scale、tcp_app_win和tcp_app_win=0默认值情况下QTCPH口大小?5535。默认gؓ
87380
maxQ用于TCP socket接收~冲的内存最大倹{该g
会媄响 net.core.wmem_maxQ?静?选择参数 SO_SNDBUF则不受该值媄响。默认gؓ 128K。默认gؓ
87380*2 bytes。(可以看出Q?max的设|最好是default的两?对于NAT来说主要该增加它,我的|络?
为?1200 131072 204800Q?br />
tcp_mem(3个INTEGER变量)Qlow, pressure, high
lowQ当TCP使用了低于该值的内存面数时QTCP不会考虑释放内存?理想情况下,q个值应与指定给 tcp_wmem 的第 2 个值相匚w - q第 2 个D明,最大页面大乘以最大ƈ发请求数除以大?131072 * 300 / 4096)。?
pressureQ?
当TCP使用了超q该值的内存面数量ӞTCP试图E_其内存用,q入pressure模式Q当内存消耗低于low值时则退出pressure?
态?理想情况下这个值应该是 TCP 可以使用的ȝ冲区大小的最大值?204800 * 300 / 4096)。?
highQ允许所有tcp sockets
用于排队~冲数据报的面量?如果过q个|TCP q接被拒绝Q这是Z么不要o其过于保守?512000 * 300 / 4096) ?
原因了。 在q种情况下,提供的h值很大,它能处理很多q接Q是所预期的?.5 倍;或者现有q接能够传输 2.5 倍的数据。 我的网l里?
192000 300000 732000)
一般情况下q些值是在系l启动时Ҏpȝ内存数量计算得到的?br />
tcp_app_win : INTEGER
默认值是31
保留max(window/2^tcp_app_win, mss)数量的窗口由于应用缓册Ӏ当?时表CZ需要缓册Ӏ?br />
tcp_adv_win_scale : INTEGER
默认gؓ2
计算~冲开销bytes/2^tcp_adv_win_scale(如果tcp_adv_win_scale > 0)或者bytes-bytes/2^(-tcp_adv_win_scale)(如果tcp_adv_win_scale <= 0Q?br />
tcp_rfc1337 :BOOLEAN
~省gؓ0
q个开兛_以启动对于在RFC1337中描q的"tcp 的time-wait暗杀危机"问题的修复。启用后Q内核将丢弃那些发往time-wait状态TCP套接字的RST ?
tcp_low_latency : BOOLEAN
~省gؓ0
允许 TCP/IP 栈适应在高吞吐量情况下低g时的情况Q这个选项一般情形是的禁用?但在构徏Beowulf 集群的时?打开它很有帮?
tcp_westwood :BOOLEAN
~省gؓ0
启用发送者端的拥塞控制算法,它可以维护对吞吐量的评估Qƈ试图对带宽的整体利用情况q行优化Q对于 WAN 通信来说应该启用q个选项?br />
tcp_bic :BOOLEAN
~省gؓ0
为快速长距离|络启用 Binary Increase CongestionQ这样可以更好地利用以 GB 速度q行操作的链接;对于 WAN 通信应该启用q个选项?br />
# 以下一Dؓ抉|syn flooddQ^时徏议关?br />
sysctl -w net.ipv4.tcp_syncookies=1 # tcp syncookieQ默认关?br />
sysctl -w net.ipv4.tcp_max_syn_backlog=1280 # syn队列Q默?024Q?gt; 1280可能工作不稳定,需要修改内核源码参?br />
sysctl -w net.ipv4.tcp_synack_retries=2 # syn-ack握手状态重试次敎ͼ默认5Q遭受syn-floodd时改??
sysctl -w net.ipv4.tcp_syn_retries=2 # 外向syn握手重试ơ数Q默?
# 以下一Dؓ应对tcp connectq接耗尽dQ如果开启iptables connlimit模块可禁?br />
# 有严重连接性能影响和不E_因素Q慎?br />
sysctl -w tcp_tw_recycle=1 # 默认0Qtw快速回?br />
sysctl -w tcp_tw_reuse=1 # 默认0Qtw重用
sysctl -w tcp_keepalive_intvl=60 # 默认75Qtcp keeplive探测轮询旉
sysctl -w tcp_keepalive_probes=3 # 默认9Qtcp keeplive探测轮询ơ数
sysctl -w tcp_keepalive_time=1800 # 默认7200Qtcp keeplive旉
sysctl -w tcp_fin_timeout=30 # 默认60Qtcp fin状态超时时?br />
#sysctl -w net.ipv4.tcp_retries1=2 # tcpq接重传参数Q慎?br />
#sysctl -w net.ipv4.tcp_retries2=8
sysctl -w net.ipv4.ip_conntrack_max=65535 # 增大iptables状态跟t表
待验证:
1.Q客L问题Q?
包阻塞的情况多发生于~冲区域充满了数据,客户端不再进行读取操作时?
q种情况下,可能是由于客L的处理节奏慢于接受包的速度Q可以考虑
包处理q程攑օU程处理Q而对包的接受采用d的方式?
2.Q服务器端问题)
׃数据包头中部分变量的cd定义不合理而引起包的流水号界或溢出,
都可能导致服务器端出现core文g或异常停止。徏议如果有在包头中定义
水LQ用long型变量?
3.Q协议包问题Q?
在大数据量传输中Q尽量减网l资源的重复使用ơ数Q所以在|络状况
佳的情况下,原有的包体长度适当的扩大。如2k扩大?0k左右Q?
同时可以减少客户端的处理ơ数?br />
]]>
写入Blob字段和写入其它类型字D늚方式非常不同Q因为Blob自n有一个cursorQ你必须使用cursor对blobq行操作Q因而你在写入Blob之前Q必获得cursor才能q行写入Q那么如何获得Blob的cursor呢?
q需要你先插入一个empty的blobQ这创Z个blob的cursorQ然后你再把q个empty的blob的cursor用select查询出来Q这样通过两步操作Q你p得了blob的cursorQ可以真正的写入blob数据了?
看下面的JDBC的demoQ把oraclejdbc.jarq个二进制文件写入数据库表javatest的content字段(q是一个blob型字D?
[code:1]import java.sql.*;
import java.io.*;
import oracle.sql.*;
public class WriteBlob {
public static void main(String[] args) {
try {
DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:orcl","fankai","fankai");
conn.setAutoCommit(false);
BLOB blob = null;
PreparedStatement pstmt = conn.prepareStatement("insert into javatest(name,content) values(?,empty_blob())");
pstmt.setString(1,"fankai");
pstmt.executeUpdate();
pstmt.close();
pstmt = conn.prepareStatement("select content from javatest where name= ? for update");
pstmt.setString(1,"fankai");
ResultSet rset = pstmt.executeQuery();
if (rset.next()) blob = (BLOB) rset.getBlob(1);
String fileName = "oraclejdbc.jar";
File f = new File(fileName);
FileInputStream fin = new FileInputStream(f);
System.out.println("file size = " + fin.available());
pstmt = conn.prepareStatement("update javatest set content=? where name=?");
OutputStream out = blob.getBinaryOutputStream();
int count = -1, total = 0;
byte[] data = new byte[(int)fin.available()];
fin.read(data);
out.write(data);
/*
byte[] data = new byte[blob.getBufferSize()]; 另一U实现方?节省内存
while ((count = fin.read(data)) != -1) {
total += count;
out.write(data, 0, count);
}
*/
fin.close();
out.close();
pstmt.setBlob(1,blob);
pstmt.setString(2,"fankai");
pstmt.executeUpdate();
pstmt.close();
conn.commit();
conn.close();
} catch (SQLException e) {
System.err.println(e.getMessage());
e.printStackTrace();
} catch (IOException e) {
System.err.println(e.getMessage());
}
}
}[/code:1]
仔细看上例,分三步:
1、插入空blob
into javatest(name,content) values(?,empty_blob());
2、获得blob的cursor
select content from javatest where name= ? for update;
注意Q!Q必dfor updateQ这锁定该行,直至该行被修改完毕,保证不生ƈ发冲H?
3、update javatest set content=? where name=
用cursor往数据库写数据
q里面还有一点要提醒大家Q?
JDK1.3带的JDBC2.0规范是不完善的,只有读Blob的接口,而没有写Blob的接口,JDK1.4带的JDBC3.0加入了写
Blob的接口。你可以使用JDBC3.0的接口,也可以直接用Oracle的JDBC的APIQ我在上例中使用了Oracle的JDBC的API?
另外要注意的是:
java.sql.Blob
oracle.sql.BLOB
注意看blob的大写Q是不一L。写E序的时候不要搞混了?
下面看看用Hibernate怎么写,原理是一LQ也要分三步Q但是代码简单很?
q是Cat对象定义
[code:1]package com.fankai;
import java.sql.Blob;
public class Cat {
private String id;
private String name;
private char sex;
private float weight;
private Blob image;
public Cat() { }
public String getId() { return id; }
public void setId(String id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public char getSex() { return sex; }
public void setSex(char sex) { this.sex = sex; }
public float getWeight() { return weight; }
public void setWeight(float weight) { this.weight = weight; }
public Blob getImage() { return image; }
public void setImage(Blob image) { this.image = image;}
}[/code:1]
q是Cat.hbm.xml
[code:1]<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping SYSTEM "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapping>
<class name="com.fankai.Cat" table="cat">
<!--jcs-cache usage="read-only"/-->
<id name="id" unsaved-value="null">
<generator class="uuid.hex"/>
</id>
<property name="name" length="16" not-null="true"/>
<property name="sex" length="1" not-null="true"/>
<property name="weight" />
<property name="image" />
</class>
</hibernate-mapping>[/code:1]
下面是完整的用Hibernate写入Blob的例子,相比JDBCQ已l简单轻村֤了,也不用写那些OracleҎ的sql了:
[code:1]package com.fankai;
import java.sql.Blob;
import net.sf.hibernate.*;
import oracle.sql.*;
import java.io.*;
public class TestCatHibernate {
public static void testBlob() {
Session s = null;
byte[] buffer = new byte[1];
buffer[0] = 1;
try {
SessionFactory sf = HibernateSessionFactory.getSessionFactory();
s = sf.openSession();
Transaction tx = s.beginTransaction();
Cat c = new Cat();
c.setName("Robbin");
c.setImage(Hibernate.createBlob(buffer));
s.save(c);
s.flush();
s.refresh(c, LockMode.UPGRADE);
BLOB blob = (BLOB) c.getImage();
OutputStream out = blob.getBinaryOutputStream();
String fileName = "oraclejdbc.jar";
File f = new File(fileName);
FileInputStream fin = new FileInputStream(f);
int count = -1, total = 0;
byte[] data = new byte[(int)fin.available()];
fin.read(data);
out.write(data);
fin.close();
out.close();
s.flush();
tx.commit();
} catch (Exception e) {
System.out.println(e.getMessage());
} finally {
if (s != null)
try {
s.close();
} catch (Exception e) {}
}
}
}[/code:1]
]]>
配置JavabeansӞ出现错误信息"没有扑ֈ本地Ҏ?java.lang.UnsatisfiedLinkError"?
错误原因:
trsbean.jar对应的本地方法库trsbean.dll或libtrsbean.so配置不正?
解决ҎQ?
1.认安装介质在传输过E中没有损坏Q如ftp传输需要用二q制模式?
2.认操作pȝ的版本和JDK的位数?
JavaBeans的位数必dJDK的位C持一_?2位JDK必须使用32位JavaBeans?
JavaBeans的^台必dJDK的^C持一致。如AIX5.1q_的JavaBeans只支持AIX5.1/5.2/5.3Q不支持AIX4.3或其它厂商的Unix?
3.注意libtrsbean.so的文件属性?
如HPq_Q必设|libtrsbean.sl的可执行权限?
4.注意trsbean.dll/libtrsbean.so的存放\径,应该包含在JAVA本地Ҏ库的搜烦路径?
Windowsq_Q?
JAVA本地Ҏ库的搜烦路径包含环境变量PATH?JAVA_HOME%/jre/binQ?
Linux/Solarisq_Q?
JAVA本地Ҏ库的搜烦路径包含环境变量LD_LIBRARY_PATHQ?
AIXq_:
JAVA本地Ҏ库的搜烦路径包含环境变量LIBPATHQ?
HPUXq_:
JAVA本地Ҏ库的搜烦路径包含环境变量SHLIB_PATHQ?
JDK1.4以上版本Q也可以在java启动参数中设|系l属性java.library.path, 指向libtrsbean.so所在的目录Q如java -Djava.library.path="/home/trs/trsbean"
通常情况下,在应用服务器的启动脚本中指定本地Ҏ库的搜烦路径。 ?
问题2:
多套应用同时使用javabeanQ出现错误信?java.lang.UnsatisfiedLinkError: Native Library trsbean.dll already loaded in another classloader"?
错误原因Q?
一个JAVAq程QJAVA本地Ҏ库只能被加蝲一ơ,如果被多ơ加载就会出现该错误?
解决ҎQ?
保证在一个JAVA虚拟ZQTRS Javabeans的本地方法库只被加蝲一ơ?
如果应用服务器上的多个应用用TRS JavaBeansQ不能将trsbean.jar部v到每个应用下?
只保留一套TRS JavaBeansQ在应用服务器中配置全局的trsbean.jar?
以Tomcat4.1.36, WindowspȝZQ?
trsbean.jar攑֜%TOMCAT_HOME%/common/libQ或修改启动脚本中的CLASSPATH变量?
trsbean.dll攑֜pȝ动态库的搜索\径?
问题3:
Z么TRSConnection和TRSResultSet需要close? 能否TRS对象攑֜WEB应用的Session?
{案3:
TRSConnection对应TRSq接, TRSResultSet对应TRSl果集,占用量的Native内存?
如果E序不调用closeҎ关闭Q会造成Native内存泄露Q严重时Djavaq程出现OutOfMemory错误?
如果TRS对象攑֜Session中,WEB客户端快速翻|会导致记录内容的不一致?
set JAVA_OPTS=%JAVA_OPTS% -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port="9004" -Dcom.sun.management.jmxremote.authenticate="false" -Dcom.sun.management.jmxremote.ssl="false"
JAVA_OPTS="$JAVA_OPTS -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9004 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false"
linux下要讄
export LANG=C
C--对英?ASCII 环境(不知道还有没有别的含义了)
(一)环境说明
(1)服务器有4収ͼ一台安装apache,三台安装tomcat
(2)apache2.0.55、tomcat5.5.15、jk2.0.4、jdk1.5.6或jdk1.4.2
(3)ip配置,一台安装apache的ip?92.168.0.88,三台安装tomcat的服务器ip分别?92.168.0.1/2/4
(?安装q程
(1)在三台要安装tomcat的服务器上先安装jdk
(2)配置jdk的安装\?在环境变量path中加入jdk的bin路径,新徏环境变量JAVA_HOME指向jdk的安装\?br />(3)在三台要安装tomcat的服务器上分别安装tomcat,调试三个tomcat到能够正常启?br />(4)tomcat的默认WEB服务端口?080,默认的模式是单独服务,我的三个tomcat的WEB服务端口修改?080/8888/9999
修改位置为tomcat的安装目录下的conf/server.xml
修改前的配置?br /> <Connector port="8080" maxHttpHeaderSize="8192"
maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
enableLookups="false" redirectPort="8443" acceptCount="100"
connectionTimeout="20000" disableUploadTimeout="true" />
修改后的配置?br /> <Connector port="7080" maxHttpHeaderSize="8192"
maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
enableLookups="false" redirectPort="8443" acceptCount="100"
connectionTimeout="20000" disableUploadTimeout="true" />
依次修改每个tomcat的监听端?7080/8888/9999)
(5)分别试每个tomcat的启动是否正?br />http://192.168.0.1:7080
http://192.168.0.2:8888
http://192.168.0.4:9999
(?负蝲均衡配置q程
(1)在那台要安装apache的服务器上安装apache2.0.55,我的安装路径为默认C:\Program Files\Apache Group\Apache2
(2)安装后测试apache能否正常启动Q调试到能够正常启动http://192.168.0.88
(3)下蝲jk2.0.4后解压羃文g
(4)解压羃后的目录中的modules目录中的mod_jk2.so文g复制到apache的安装目录下的modules目录?我的为C:\Program Files\Apache Group\Apache2\modules
(5)修改apache的安装目录中的conf目录的配|文件httpd.confQ在文g中加LoadModule模块配置信息的最后加上一句LoadModule jk2_module modules/mod_jk2.so
(6)分别修改三个tomcat的配|文件conf/server.xmlQ修改内容如?br />修改?br /> <!-- An Engine represents the entry point (within Catalina) that processes
every request. The Engine implementation for Tomcat stand alone
analyzes the HTTP headers included with the request, and passes them
on to the appropriate Host (virtual host). -->
<!-- You should set jvmRoute to support load-balancing via AJP ie :
<Engine name="Standalone" defaultHost="localhost" jvmRoute="jvm1">
-->
<!-- Define the top level container in our container hierarchy -->
<Engine name="Catalina" defaultHost="localhost">
修改?br /> <!-- An Engine represents the entry point (within Catalina) that processes
every request. The Engine implementation for Tomcat stand alone
analyzes the HTTP headers included with the request, and passes them
on to the appropriate Host (virtual host). -->
<!-- You should set jvmRoute to support load-balancing via AJP ie :-->
<Engine name="Standalone" defaultHost="localhost" jvmRoute="tomcat1">
<!-- Define the top level container in our container hierarchy
<Engine name="Catalina" defaultHost="localhost">
-->
其中的jvmRoute="jvm1"分别修改为jvmRoute="tomcat1"和jvmRoute="tomcat2"和jvmRoute="tomcat3"
(7)然后重启三个tomcatQ调试能够正常启动?br />(8)在apache的安装目录中的conf目录下创建文件workers2.propertieQ写入文件内容如?br />
# fine the communication channel
[channel.socket:192.168.0.1:8009]
info=Ajp13 forwarding over socket
#配置W一个服务器
tomcatId=tomcat1 #要和tomcat的配|文件server.xml中的jvmRoute="tomcat1"名称一?br />debug=0
lb_factor=1 #负蝲q因子Q数字越大请求被分配的几率越?br />
# Define the communication channel
[channel.socket:192.168.0.2:8009]
info=Ajp13 forwarding over socket
tomcatId=tomcat2
debug=0
lb_factor=1
# Define the communication channel
[channel.socket:192.168.0.4:8009]
info=Ajp13 forwarding over socket
tomcatId=tomcat3
debug=0
lb_factor=1
[status:]
info=Status worker, displays runtime information.
[uri:/jkstatus.jsp]
info=Display status information and checks the config file for changes.
group=status:
[uri:/*]
info=Map the whole webapp
debug=0
(9)在三个tomcat的安装目录中的webapps建立相同的应?我和应用目录名ؓTomcatDemo,在三个应用目录中建立相同 WEB-INF目录和页面index.jsp,index.jsp的页面内容如?br /><%@ page contentType="text/html; charset=GBK" %>
<%@ page import="java.util.*" %>
<html><head><title>Cluster App Test</title></head>
<body>
Server Info:
<%
out.println(request.getLocalAddr() + " : " + request.getLocalPort()+"<br>");%>
<%
out.println("<br> ID " + session.getId()+"<br>");
// 如果有新?Session 属性设|?br /> String dataName = request.getParameter("dataName");
if (dataName != null && dataName.length() > 0) {
String dataValue = request.getParameter("dataValue");
session.setAttribute(dataName, dataValue);
}
out.print("<b>Session 列表</b>");
Enumeration e = session.getAttributeNames();
while (e.hasMoreElements()) {
String name = (String)e.nextElement();
String value = session.getAttribute(name).toString();
out.println( name + " = " + value+"<br>");
System.out.println( name + " = " + value);
}
%>
<form action="index.jsp" method="POST">
名称:<input type=text size=20 name="dataName">
<br>
?<input type=text size=20 name="dataValue">
<br>
<input type=submit>
</form>
</body>
</html>
(10)重启apache服务器和三个tomcat服务?到此负蝲 均衡已配|完成。测试负载均衡先试apache,讉Khttp://192.168.0.88/jkstatus.jsp
能否正常讉KQƈ查询其中的内容,有三个tomcat的相关配|信息和负蝲说明,讉Khttp://192.168.0.88/TomcatDemo/index.jsp看能够运?
能运行,则已建立负蝲均衡?br />(?tomcat集群配置
(1)负蝲均衡配置的条件下配置tomcat集群
(2)分别修改三个tomcat的配|文件conf/server.xml,修改内容如下
修改?br /> <!--
<Cluster className="org.apache.catalina.cluster.tcp.SimpleTcpCluster"
managerClassName="org.apache.catalina.cluster.session.DeltaManager"
expireSessionsOnShutdown="false"
useDirtyFlag="true"
notifyListenersOnReplication="true">
<Membership
className="org.apache.catalina.cluster.mcast.McastService"
mcastAddr="228.0.0.4"
mcastPort="45564"
mcastFrequency="500"
mcastDropTime="3000"/>
<Receiver
className="org.apache.catalina.cluster.tcp.ReplicationListener"
tcpListenAddress="auto"
tcpListenPort="4001"
tcpSelectorTimeout="100"
tcpThreadCount="6"/>
<Sender
className="org.apache.catalina.cluster.tcp.ReplicationTransmitter"
replicationMode="pooled"
ackTimeout="5000"/>
<Valve className="org.apache.catalina.cluster.tcp.ReplicationValve"
filter=".*\.gif;.*\.js;.*\.jpg;.*\.png;.*\.htm;.*\.html;.*\.css;.*\.txt;"/>
<Deployer className="org.apache.catalina.cluster.deploy.FarmWarDeployer"
tempDir="/tmp/war-temp/"
deployDir="/tmp/war-deploy/"
watchDir="/tmp/war-listen/"
watchEnabled="false"/>
<ClusterListener className="org.apache.catalina.cluster.session.ClusterSessionListener"/>
</Cluster>
-->
修改?br /> <!-- modify by whh -->
<Cluster className="org.apache.catalina.cluster.tcp.SimpleTcpCluster"
managerClassName="org.apache.catalina.cluster.session.DeltaManager"
expireSessionsOnShutdown="false"
useDirtyFlag="true"
notifyListenersOnReplication="true">
<Membership
className="org.apache.catalina.cluster.mcast.McastService"
mcastAddr="228.0.0.4"
mcastPort="45564"
mcastFrequency="500"
mcastDropTime="3000"/>
<Receiver
className="org.apache.catalina.cluster.tcp.ReplicationListener"
tcpListenAddress="auto"
tcpListenPort="4001"
tcpSelectorTimeout="100"
tcpThreadCount="6"/>
<Sender
className="org.apache.catalina.cluster.tcp.ReplicationTransmitter"
replicationMode="pooled"
ackTimeout="5000"/>
<Valve className="org.apache.catalina.cluster.tcp.ReplicationValve"
filter=".*\.gif;.*\.js;.*\.jpg;.*\.png;.*\.htm;.*\.html;.*\.css;.*\.txt;"/>
<Deployer className="org.apache.catalina.cluster.deploy.FarmWarDeployer"
tempDir="/tmp/war-temp/"
deployDir="/tmp/war-deploy/"
watchDir="/tmp/war-listen/"
watchEnabled="false"/>
<ClusterListener className="org.apache.catalina.cluster.session.ClusterSessionListener"/>
</Cluster>
<!-- modify by whh -->
集配|选项的注释放开卛_Q如上?br />(3)重启三个tomcat。到此tomcat的集已配置完成?/p>
(?应用配置
对于要进行负载和集群的的tomcat目录下的webapps中的应用中的WEB-INF中的web.xml文g要添加如下一句配|?br /><distributable/>
配置?br /><?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4">
<display-name>TomcatDemo</display-name>
</web-app>
配置?br /><?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4">
<display-name>TomcatDemo</display-name>
<distributable/>
</web-app>
?tomcat集群是怎么处理session的阿
{?在tomcat做集之后,每个tomcat之间自动Ҏtomcat的配|文件中的参数进行session复制,
对于一个客L对说Q只要是同一个IPQ那它每ơ上传的sessionID是一L?
3. 修改Apache_Home/conf/httpd.confQ加入如下代码:
3.1 LoadModule weblogic_module modules/mod_wl_20.so
3.2 新增一个IfModule定义Q对于non-clustered WebLogic Server包括WebLogicHost与WebLogicPort参数Q对于Weblogic Server Cluster包括WebLogicCluster参数Q?br />例:<IfModule mod_weblogic.c>
WebLogicHost 127.0.0.1
WebLogicPort 7001
</IfModule>
<IfModule mod_weblogic.c>
WebLogicCluster 192.168.0.1Q?001,192.168.0.2:7001
</IfModule>
3.3 对于proxy requests by MIME typeQ可以在IfMoudle中增加参数MatchExpression,可以有多个;
例:<IfModule mod_weblogic.c>
WebLogicHost 127.0.0.1
WebLogicPort 7001
MatchExpression *.jsp
MatchExpression *.do
</IfModule>
3.4 对于proxying requests by pathQ可以新增一个Location的定? 参数SetHandler用于指定Apache HTTP server plug-in的模式;
例:<Location /web>
SetHandler weblogic-handler
WebLogicHost 192.168.70.78
WebLogicPort 7001
</Location>
4. 重启BEA Weblogic ServerQ?br />5. 重启Apache HTTP ServerQ?br />6. 打开IEQ输入设定的server nameQ出现系l的d面Q则说明配置成功?br />7. 对于后期新增的Weblogic server实例Q只需要在httpd.conf增加一个Location定义卛_Q需要包括参数SetHandler, WebLogicHost, WebLogicPort;
1).
使用服务lg的客L可以选择使用WSDL接口?span lang="EN-US">Java接口?span lang="EN-US">
服务lg提供l别的服务调用的入口?span lang="EN-US">InterfaceQ接口)。而服务组件本w可能也需要调用别的服务,q个调用出口?span lang="EN-US">ReferenceQ引用)。无论是接口q是引用Q其调用规范都是WSDL?span lang="EN-US">Java接口?span lang="EN-US">
2).SCA
服务lg与传l组件的主要区别在于Q?span lang="EN-US">
1
Q?服务lg往往是粗_度的,而传l组件以l粒度居多?span lang="EN-US">
2
Q?服务lg的接口是标准的,主要?span lang="EN-US">WSDL接口Q而传l组件常以具?span lang="EN-US">API形式出现?span lang="EN-US">
3
Q?服务lg的实C语言是无关的Q而传l组件常l定某种特定的语a?span lang="EN-US">
4
Q?服务lg可以通过lg容器提供QoS的服务,而传l组件完全由E序代码直接控制?span lang="EN-US">
3).
服务模块Q?span lang="EN-US">ModuleQ?span lang="EN-US">
服务模块Q简U模块)׃个或多个h内在业务联系的服务组件构成。把多少服务lg攑֜一个模块中Q或者把哪些服务lg攑֜一起主要取决于业务需求和部v上灵zL的要求
4).
导入Q?span lang="EN-US">ImportQ和导出Q?span lang="EN-US">ExportQ?span lang="EN-US">
两个Ҏ?span lang="EN-US">"端点"Q一个是导入Q?span lang="EN-US">ImportQ,它的作用是得模块中的服务组件可以调用模块外部的服务。另一个是导出Q?span lang="EN-US">ExportQ,它的作用是得模块外部的应用可以调用模块中的服务lg?span lang="EN-US">
导入端点提供了四U绑定方式,包括Q?span lang="EN-US">JMSl定Q?span lang="EN-US">Web Servicel定Q?span lang="EN-US">SCAl定和无状态会?span lang="EN-US">BEAN的绑定。导出端Ҏ供了三种l定方式Q包括:JMSl定Q?span lang="EN-US">Web Servicel定?span lang="EN-US">SCAl定?span lang="EN-US">
5).
׃n库(LibraryQ?span lang="EN-US">
׃n库包含的内容只有Q数据定义,接口定义Q数据映和关系。与模块最大的区别使共享库不包含服务组Ӟ因此也就不包含业务逻辑
6).Standalone Reference
模块中的服务lg是不能直接被外部Java代码使用的,Standalone Reference(端点)是Z让外部的Java代码能够使用模块中的服务lg。这个端点只有引用(ReferenceQ,而没有接口(InterfaceQ。这个引用可以调用相应的服务lg?span lang="EN-US">
7).
同步调用和异步调?span lang="EN-US">
面对是基于粗_度的服务组Ӟ面对的是一些需要比较长旉才能有响应的应用场景Q那么我们就需要一U非d式调用方式,卛_步调用方式?span lang="EN-US">
SCA
~程模式提供了三U方式的异步调用Q它们分别是Q?span lang="EN-US">
1
Q?单向调用方式?span lang="EN-US">
2
Q?延迟响应方式?span lang="EN-US">
3
Q?h回调方式?span lang="EN-US">
8).SCA
客户端的两种调用方式
从接口的角度Q?span lang="EN-US">SCA的客L~程模型有两U方式:
1
Q?静态调用方?span lang="EN-US">
2
Q?动态调用方?span lang="EN-US">
9).
接口cd与调用方?span lang="EN-US">
实际上客L采用哪种调用方式是与接口cd有密切的关系。当提供的接口类型是WSDLcd的,那么客户端的调用方式只能是动态调用方式。由?span lang="EN-US">WSDL?span lang="EN-US">SCA模型中主要的接口方式Q这样就D动态调用方式在SCA~程模型中非常普遍。但是如果提供的接口cd?span lang="EN-US">Javacd的,那么客户端的调用方式可以是动态调用方式,也可以是静态调用方式?span lang="EN-US">
让WebLogic先识别该应用的包Q?/font> 修改的方式就是在自己的应用中WEB-INF中新建weblogic.xml文g <!--CTYPE weblogic-web-app PUBLIC "-//BEA Systems, Inc.//DTD Web Application 8.1//EN" "http://www.bea.com/servers/wls810/dtd/weblogic810-web-jar.dt--> xml 代码
|
|
1、基本概忉|ȝ
a. 什么是Domain和Server
Domain是WebLogic Server实例的基本管理单元。所谓Domain是Q由配置为Administrator Server的WebLogic Server实例理的逻辑单元Q这个单元是有所有相兌源的集合?br /> Server是一个相对独立的Qؓ实现某些特定功能而结合在一L单元?br />b. Domain and Server的关p?br />一个Domain 可以包含一个或多个WebLogic Server实例Q甚xServer集群。一个Domain中有一个且只能有一个Server 担Q理Server的功能,其它的Server具体实现一个特定的逻辑功能?/p>
c. WebLogic集群的体pȝ?br /> 1. 单层混合型的集群架构
q种架构所有的Web应用以及相关的服务应用全部置于集中的单一WLS实例中,q种架构的优势在于:
>> 易于理
>> 灉|的负载^衡机?br /> >> 更强的安全控?br /> 2. 多层l构的集架?br /> q种架构使用两个WLS集群Q一个放|表静态内容和集群ServletQ另一个放|集EJB。一般应用于下面q些情况Q?br /> >> 在负载^衡机刉要调用集EJB中的ҎӞ
>> 在提供内容与提供对象的服务之间需要更大的机动性时Q?br /> >> 在需要更高的pȝE_性时Q?/p>
d. 配置集群应用的必要条?br /> 1. 集群中的所有Server必须位于同一|段Qƈ且必LIPq播(UDP)可到辄
2. 集群中的所有Server必须使用相同的版?包括Service Pack
3. 集群中的Server必须使用怹的静态IP地址。动态IP地址分配不能用于集群环境。如果服务器位于防火墙后面,而客h位于防火墙外面,那么服务器必L公共的静态IP地址Q只有这P客户端才能访问服务器
4. 要以CLUSTER方式q行Q必L包含CLUSTER许可的LICENSE才行.
2、集配|ȝ
a. 配置集群可以在新建域(Domain)的时候进行,也可以在一个现有的域的基础上进?br />b. 在没有集的环境下,新徏一个域时可以将理服务?Admin Server)作ؓ事务处理服务器用,否则理服务器应该指向集的Admin Server所在的机器?br />c. 启动Managed Server的方法有两种Q一U是以命令行的方式,? startManagedWebLoigc managedserver http://adminserver_address/Q第二种是在WebLogic理控制C启动此时必须先启动NodeManagerQƈ且在一台机器上的多个Server只需要启一?NodeManager实例。两U启动方式下Weblogic的后台输出是不一LQ前者输出到控制台窗口,后者输出到ModeManager目录下的日志文g中,一个Server一个日志文件?br />d. 必须通过HttpClusterServlet实现集群的自动请求{发,也就是说必须创徏一个Server作ؓ代理服务?proxy Server)?br /> 在代理服务器上部|缺省的Web应用Q该应用的WEB-INF目录包括下两个文Ӟ其中web.xml内容如下Q?br /> <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" " <web-app id="WebApp_ID">
<display-name>NJGS Web Application</display-name>
<servlet>
<servlet-name>HttpClusterServlet</servlet-name>
<servlet-class>
weblogic.servlet.proxy.HttpClusterServlet
</servlet-class>
<init-param>
<param-name>WebLogicCluster</param-name>
<param-value>
localhost:7011|localhost:7012|localhost:7013
</param-value>
</init-param>
<init-param>
<param-name>DebugConfigInfo</param-name>
<param-value>ON</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>HttpClusterServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>HttpClusterServlet</servlet-name>
<url-pattern>*.jsp</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>HttpClusterServlet</servlet-name>
<url-pattern>*.html</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>HttpClusterServlet</servlet-name>
<url-pattern>*.htm</url-pattern>
</servlet-mapping>
</web-app>
weblogic.xml文g的内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE weblogic-web-app PUBLIC "-//BEA Systems, Inc.//DTD Web Application 8.1//EN" "<weblogic-web-app>
<context-root>/</context-root>
</weblogic-web-app>
注意上述context-root的内容必Mؓ /
e. Web应用向集上部vӞ必须选择部v到整个集或者集中的某些服务器QHttph的{发由代理服务器自动处理?br />f. 可以写个单的面Qƈ且用JMeter模拟上百个请求同时访问该面?试集群功能。请求的格式?http://proxyserver_address/应用?试jps面
E:\bea\user_projects\domains\mydomain>startmanagedweblogic managed2 http://IP:7001
cd
startweblogic
startmanagedweblogic managed2 http://IP:7001
mvn archetype:create -DgroupId=[your project's group id] -DartifactId=[your project's artifact id] -DarchetypeArtifactId=maven-archetype-quickstartmvn archetype:create -DgroupId=[your project's group id] -DartifactId=[your project's artifact id] -DarchetypeArtifactId=maven-archetype-j2ee-simplemvn archetype:create -DgroupId=[your project's group id] -DartifactId=[your project's artifact id] -DarchetypeArtifactId=maven-archetype-webappmvn archetype:create -DgroupId=[your project's group id] -DartifactId=[your project's artifact id] -DarchetypeArtifactId=maven-archetype-site-simplemvn archetype:create -DgroupId=[your project's group id] -DartifactId=[your project's artifact id] -DarchetypeArtifactId=maven-archetype-sitemvn archetype:create -DgroupId=[your project's group id] -DartifactId=[your project's artifact id] -DarchetypeArtifactId=maven-archetype-portletmvn archetype:create -DgroupId=[your project's group id] -DartifactId=[your project's artifact id] -DarchetypeArtifactId=maven-archetype-mojomvn archetype:create -DgroupId=[your project's group id] -DartifactId=[your project's artifact id] -DarchetypeArtifactId=maven-archetype-archetype
IDEA 6.0已经发布Q好多h抱怨反应速度慢,内存消耗大。IDEA 6.0增加了不新Ҏ,E序也更大,内存占用肯定也会提高。在q篇文章我们x讨一下这斚w的问题,通过相关的设|,让你的IDEA快v来,更稳定?br /> IntelliJ IDEA是JavaE序Q所以性能调整因从JVM和程序两斚w考虑。对于JVM的调_可能个h看法都不一Pq样我们l出一个推荐方案,然后l你做一说明Q你也可以在此基上做更个性的修改。下面的截图是根据“IDEA VM Options”插件做的,该插件可以修改idea.exe.vmoptions文g内容Q即使升U版本也不用担心? |
![]() |
-Xms256m |
![]() |
取消“Synchronize file on frame activation”和“Save files on frame deactivation”的选择。在IDEA中,采用多线E读写文Ӟ但线E写Q而且盘d非常耗费旉Q所以我们徏议取消这两个选项Q否则在IDEA和其他程序切换时Q你会发现磁盘操作比较频J。同时我们选择“Save files automatically”,q将其设|ؓ30U,q样IDEA依然可以自动保持文g。做以上的设|,可能有一点不方便。如我们~辑一个jsp文gQ然后切换到览器刷斎ͼ获得最新的信息。但是在切换到浏览器ӞIDEA不会自动保存,所有信息不是最新的。所以在每次切换Ӟ你需要按下Ctrl+SQ保存文件。这样你需要了解哪些文件被更改了,l这些文件一个标识?在IDEA中,你需要做以下讄, q样被修改的文g会以*h识出来,你可以及时保存相关的文g? |
![]() |
ȝQ?/strong>通过以上的设|,我们怿会提高IDEA的性能。当然这不表CIDEA的默认配|是错误的,如同数据库软g一P提供了一个标准的配置Q具体的一些性能调整可能要根据实际情늡定?/p> |
1、下载:
apache2.0.50?a >http://apache.org下蝲
tomcat5.0.28?a >http://jakarta.apache.org下蝲
module_jk2?a >http://jakarta.apache.org下蝲
2
Apache到D:\Apache Group\Apache2
Tomcat到E:\work\jakarta-tomcat-5.0.28
module文g为jakarta-tomcat-connectors-jk2.0.4-win32-apache2.0.49.zip 解压~,modules/mod_jk2.so拯?br /> D:\Apache Group\Apache2\modules下,conf/workers2.properties.sample拯到D:\Apache Group\Apache2\conf下,
q改名ؓworker1.properties
3、修改D:\Apache Group\Apache2\conf\httpd.confQ增?br /> LoadModule jk2_module "modules/mod_jk2.so"
JkSet config.file "conf/workers2.properties"
Apache配置完毕Q重新启动Apache
4、tomcat默认支持ajp1.3的jk2q接Q所以只需要配|apache可以,剩下的就是将需要访问的目录增加?br /> worker2.properties可以了Q默认ؓ
[shm]
info=Scoreboard. Requried for reconfiguration and status with multiprocess servers.
file=anon
# Defines a load balancer named lb. Use even if you only have one machine.
[lb:lb]
# Example socket channel, override port and host.
[channel.socket:localhost:8009]
port=8009
host=127.0.0.1
# define the worker
[ajp13:localhost:8009]
channel=channel.socket:localhost:8009
group=lb
# Map the Tomcat examples webapp to the Web server uri space
[uri:/examples/*]
group=lb
[status:]
info=Status worker, displays runtime information
[uri:/jkstatus/*]
info=The Tomcat /jkstatus handler
group=status:
[shm]
info=Scoreboard. Requried for reconfiguration and status with multiprocess servers.
file=D:/Apache Group/Apache2/logs/jk2.shm
size=1048576
需要修改一下apache的默认目录,然后我增加了两个目录/servlets-examples?axisQ得到如?/p>
# Defines a load balancer named lb. Use even if you only have one machine.
[lb:lb]
# Example socket channel, override port and host.
[channel.socket:localhost:8009]
port=8009
host=localhost
# define the worker
[ajp13:localhost:8009]
channel=channel.socket:localhost:8009
group=lb
# Map the Tomcat examples webapp to the Web server uri space
[uri:/jsp-examples/*]
group=lb
[uri:/bbs/*]
group=lb
[uri:/servlets-examples/*]
group=lb
[uri:/axis/*]
group=lb
[status:]
info=Status worker, displays runtime information
[uri:/jkstatus/*]
info=The Tomcat /jkstatus handler
group=status:
[uri:/*.jsp]
worker=ajp13:localhost:8009
重新启动apache,tomcat
讉K
http://localhost/jkstatus/
http://localhost/servlets-examples/
http://localhost/axis/
http://localhost:8080/servlets-examples/
http://localhost:8080/axis
看一下结果,如果q要增加新的目录Q只要照上面操作卛_
private String SN;
private String A_NUM;
public String getA_NUM() {
return A_NUM;
}
public void setA_NUM(String a_num) {
A_NUM = a_num;
}
?br />
q段代码用Apache的Common中的Util反射得不到预期的结?br /><bean:write name="stockGuessActionForm" property="A_NUM" /> 出现错误
<bean:write name="stockGuessActionForm" property="a_NUM" /> 可以得到l果
//Apache的Common中的Util要求javaBean中Property变量要求两个字母要大写都大写Q小写都写Q否则反失?br />NAME 成功
Name p|
NaME p|
Q=Q=Q=Q=Q=Q=Q=
public static BeanInfo getBeanInfo(Class<?> beanClass)
throws IntrospectionException
{
if (!ReflectUtil.isPackageAccessible(beanClass)) {
return (new Introspector(beanClass, null, USE_ALL_BEANINFO)).getBeanInfo();
}
...................
}
private BeanInfo getBeanInfo() throws IntrospectionException {
..........
PropertyDescriptor pds[] = getTargetPropertyInfo();
.........
}
private PropertyDescriptor[] getTargetPropertyInfo() {
..........
if{
............
}else {
// Apply some reflection to the current class.
// First get an array of all the public methods at this level
Method methodList[] = getPublicDeclaredMethods(beanClass);
// Now analyze each method.
for (int i = 0; i < methodList.length; i++) {
Method method = methodList[i];
if (method == null) {
continue;
}
// skip static methods.
int mods = method.getModifiers();
if (Modifier.isStatic(mods)) {
continue;
}
String name = method.getName();
Class argTypes[] = method.getParameterTypes();
Class resultType = method.getReturnType();
int argCount = argTypes.length;
PropertyDescriptor pd = null;
if (name.length() <= 3 && !name.startsWith(IS_PREFIX)) {
// Optimization. Don't bother with invalid propertyNames.
continue;
}
try {
if (argCount == 0) {
if (name.startsWith(GET_PREFIX)) {
// Simple getter
============================文问题就出现在这?decapitalize(name.substring(3)=========
pd = new PropertyDescriptor(decapitalize(name.substring(3)),
method, null);
} else if (resultType == boolean.class && name.startsWith(IS_PREFIX)) {
// Boolean getter
pd = new PropertyDescriptor(decapitalize(name.substring(2)),
method, null);
}
............................................
}
}
public static String decapitalize(String name) {
if (name == null || name.length() == 0) {
return name;
}
if (name.length() > 1 && Character.isUpperCase(name.charAt(1)) &&
Character.isUpperCase(name.charAt(0))){
return name;
}
char chars[] = name.toCharArray();
chars[0] = Character.toLowerCase(chars[0]);
return new String(chars);
}
// pd = new PropertyDescriptor(decapitalize(name.substring(3)),
//是在这里了decapitalize(name)中要求Property变量要求两个字母要大写都大写Q小写都写Q否则反失?br />Q否则反失?/font>
<%@ page contentType="image/jpeg" import="java.awt.*,java.awt.image.*,java.util.*,javax.imageio.*" %>
<%!
Color getRandColor(int fc,int bc){//l定范围获得随机颜色
Random random = new Random();
if(fc>255) fc=255;
if(bc>255) bc=255;
int r=fc+random.nextInt(bc-fc);
int g=fc+random.nextInt(bc-fc);
int b=fc+random.nextInt(bc-fc);
return new Color(r,g,b);
}
%>
<%
//讄面不缓?br />response.setHeader("Pragma","No-cache");
response.setHeader("Cache-Control","no-cache");
response.setDateHeader("Expires", 0);
// 在内存中创徏图象
int width=60, height=20;
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
// 获取囑Ş上下?br />Graphics g = image.getGraphics();
//生成随机c?br />Random random = new Random();
// 讑֮背景?br />g.setColor(getRandColor(200,250));
g.fillRect(0, 0, width, height);
//讑֮字体
g.setFont(new Font("Times New Roman",Font.PLAIN,18));
//画边?br />//g.setColor(new Color());
//g.drawRect(0,0,width-1,height-1);
// 随机产生155条干扰线Q图象中的认证码不易被其它E序探测?br />g.setColor(getRandColor(160,200));
for (int i=0;i<155;i++)
{
int x = random.nextInt(width);
int y = random.nextInt(height);
int xl = random.nextInt(12);
int yl = random.nextInt(12);
g.drawLine(x,y,x+xl,y+yl);
}
// 取随Z生的认证?4位数?
String sRand="";
for (int i=0;i<4;i++){
String rand=String.valueOf(random.nextInt(10));
sRand+=rand;
// 认证码昄到图象中
g.setColor(new Color(20+random.nextInt(110),20+random.nextInt(110),20+random.nextInt(110)));//调用函数出来的颜色相同,可能是因为种子太接近Q所以只能直接生?br /> g.drawString(rand,13*i+6,16);
}
// 认证码存入SESSION
session.setAttribute("rand",sRand);
// 图象生效
g.dispose();
// 输出图象到页?br />ImageIO.write(image, "JPEG", response.getOutputStream());
%>
---------------使用验证码图片的文g---------a.jsp------------------------------------
<%@ page contentType="text/html;charset=gb2312" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>认证码输入页?lt;/title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<META HTTP-EQUIV="Pragma" CONTENT="no-cache">
<META HTTP-EQUIV="Cache-Control" CONTENT="no-cache">
<META HTTP-EQUIV="Expires" CONTENT="0">
</head>
<body>
<form method=post action="check.jsp">
<table>
<tr>
<td align=left>pȝ产生的认证码Q?lt;/td>
<td><img border=0 src="image.jsp"></td>
</tr>
<tr>
<td align=left>输入上面的认证码Q?lt;/td>
<td><input type=text name=rand maxlength=4 value=""></td>
</tr>
<tr>
<td colspan=2 align=center><input type=submit value="提交?></td>
</tr>
</form>
</body>
</html>
-----------------验证的页?---------check.jsp
<%@ page contentType="text/html; charset=gb2312" language="java" import="java.sql.*" errorPage="" %>
<html>
<head>
<title>认证码验证页?lt;/title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<META HTTP-EQUIV="Pragma" CONTENT="no-cache">
<META HTTP-EQUIV="Cache-Control" CONTENT="no-cache">
<META HTTP-EQUIV="Expires" CONTENT="0">
</head>
<body>
<%
String rand = (String)session.getAttribute("rand");
String input = request.getParameter("rand");
%>
pȝ产生的认证码为: <%= rand %><br>
您输入的认证码ؓQ?<%= input %><br>
<br>
<%
if (rand.equals(input)) {
%>
<font color=green>输入相同Q认证成功!</font>
<%
} else {
%>
<font color=red>输入不同Q认证失败!</font>
<%
}
%>
</body>
</html>
public class Test1 {
public static void main(String[] args) {
// TODO 自动生成Ҏ存根
//法一
/*int r=0;
while(true){
r+=(((100-r)/2)+1);
if(r != 104)
System.out.println(r);
}*/
//法?br /> float b = 0;
float temp;
while(true){
float result = 100;
//temp = (float) ((result - (b))*0.2);
//result = result - temp;
result = (float) (result - ((result - b)*0.2));
b = result;
//if((int)result != 100)
System.out.println(result);
}
}
}
??常????E??q??????????c???传统 ??a ~?E?Ӟ E??????q????q?????出错 ??息?q????????误, ????????需 要知 ????????l?节??常, ??局 ?量errno??储??常??c?型?q??????用, ??一 个errno????能在 ????reg; ?????????掉???最 ??的C语言 E?序, ???理??常??况, ????于goto?句?Java对??常?????????的?一 个Java的Exception?一 ??q??常?????象???现??常???Ӟ 一 个Exception对象 ???了, q?????q?个??常??????里?
Java的??常?????q????????的:try, catch, throw, throws和finally?用try ???一 D?E?序, ???现?异常”, p?l??出(throws?copy; 一 个??常”, ????q??的类 ???捉(catch?copy; 它, ?最 后(finally?copy; ?~??处理 ???理???是??常???E??????式:
try { //E???} catch (ExceptionType1 e) { // 对ExceptionType1的处 ?} catch (ExceptionType2 e) { // 对ExceptionType2???throw(e); //???q?个??常?} finally { }
在??常?c????最 ???一 ????c??做Throwable。这 ?c????C?所 ?的??常??c??个??常?c??都是Throwable??cRThrowable???????cR?一 c?是ExceptionQ是 ??E???????的??常??c?????q??生它 ??c??????的??常”??一 c?是ErrorQ????了那 ?copy; ???????的??常”?????用Error?c,??????????????败?在Exception??一 ?子类RuntimeExceptionQ???E??q?????????copy; ?误作 ??????的?
??常???是Java?q??????copy;??常???作出 ?????的??如, ??q???E????一 ????除的??常”?
class Exc0 { public static void main(String args[]) { int d = 0; int a = 42/d; } }
当Java??q????Ӟ ?????Q?????一 个?异常?????E?????q???q?????况, ?q??时??出”(throw?copy; q?个??常”?说??出??????一??????薯, ???????q????理?E???会 ?????W????断, ?? ????????来查 䏀??常”?一 个??常??????????理??常???的??q????里, ????~?一 个??常???器,所 ?~???????????了?~???????印Exception的字 W??reg; ??????常???炏V????????例子 ??出?
C:\>java Exc0 java.lang.arithmeticException: / by zero at Exc0.main(Exc0.java:4)
??????????理??常?q?l?l?q?行???用try来指 ?一 ???所 有??常???E?序???在tryE???面,???一 个catch??????????的??常??c?型。例 如, ?????????????基础???的, ?它包 ?一 个tryE????一 个catch?句?
class exc1 { public static void main(string args[]) { try { int d = 0; int a = 42 / d; } catch (arithmeticexception e) { system.out.println("division by zero"); } } }
catch???????决??常??况, ?一 ?copy; ??讑ֈ ????态, q??????一 ?l?l?q?行???一 ?子程 ?????个??常”, ?q???一 U??理, ??最 外一 U?
???copy; ??下, ?一 D?E????????一 U?异常??c?????|??个catch?句, ???一 U??常?c????? 查, W?一 ???reg; ???????行?如果 一 ?c????c????话, ???c????面, ??永 q??????cR????一 ???个catch???E??的例 子?
class MultiCatch { public static void main(String args[]) { try { int a = args.length; System.out.println("a = " + a); int b = 42/a; int c[] = {1}; c[42] = 99; } catch(ArithmeticException e) { System.out.println("div by 0: " + e); } catch(ArrayIndexOutOfBoundsException e) { system.out.println("array index oob: " + e); } } }
???E??q??????敎ͼ ????一 ????的??常”, ?为a??????????copy; 一 ?????敎ͼ?????q?个??常”, ?为a?????????一 ?ArrayIndexOutOfBoundexception的??常”, ?????lc??度是1Q??lc[42]?倹{???????U????q??l?果?
C:\>java MultiCatch a = 0 div by 0: java.lang.arithmeticexception: / by zero C:\>java MutiCatch 1 a = 1 array index oob: java.lang.ArrayIndexOutOfBoundsException:42
????一 ???????????一 个try?句, ?q个 ?????部, ??一 个try???????码???遇到 一 个try?句,??常??????????面, ??所 有的try????成????一 U?的try??????U??常?q???理, ?????开Q????????q?U??常?的try?句????一 个try??????子?
class MultiNest { static void procedure() { try { int c[] = { 1 }: c[42] = 99; } catch(ArrayIndexOutOfBoundsexception e) { System.out.println("array index oob: " + e); } } public static void main(String args[]) { try { int a = args.length; system.out.println("a = " + a); int b = 42/a; procedure(); } catch(arithmeticException e) { System.out.println("div by 0: " + e); } } }
???数procedure????的try/catch?Ӟ 所 以main??d ?ArrayIndexOutOfBoundsException?
throw?????????一 个??常”??先, ???得到 一 个Throwable??????柄, ?q????到catch?句, 或?用new??W????一 个???是throw??????式?
throw ThrowableInstance;
E???在throw?????l?止, ?????????刎ͼ???????所 有try?????????????配的catch??的try块????一 ??有throw????子?
class ThrowDemo { static void demoproc() { try { throw new NullPointerException("de3mo"); } catch(NullPointerException e) { System.out.println("caught inside demoproc"); throw e; } } public static void main(String args[]) { try { demoproc(); } catch(NullPointerException e) { system.out.println("recaught: " + e); } } }
throws????一 ???????????U??常”。对 ??数Exception?c??_Java ~?????q?????一????????的??常??c?型??果??常??c?型是Error?RuntimeExceptionQ??????c, q???????用,??q??copy; ?E??????????????的??果你 ??????一 个RuntimeExceptionQ????用throws??来声 ???c?型?q???????????????法:
type method-name(arg-list) throws exception-list { }
???一 D?E?序, ????一 个??常”, ????捕捉 它, ???用throws??明?q??~???????q?
class ThrowsDemo1 { static void procedure( ) [ System.out.println("inside procedure"); throw new IllegalAccessException("demo"); } public static void main(String args[]) { procedure( ); } }
???q????~??q?去, ??需 ??????数procedure抛出 了IllegalAccessExceptionQ?q??????????数main?捕捉 它????????子:
class ThrowsDemo { static void procedure( ) throws IllegalAccessException { System.out.println("inside procedure"); throw new IllegalAccessException("demo"); } public static void main(String args[]) { try { procedure( ); } catch (IllegalAccessException e) { System.out.println("caught " + e); } } }
?????l?果:
C:\>java ThrowsDemo inside procedure caught java.lang.IllegalAccessException: demo
?一 个??常????Ӟ E?????????U??的,?q???copy; 行, ?????????reg; ??的catch?句?q???q?回?????一 D???????什 么??常?????????的, ??词finally??????q??一D???的?????有catch?句,finallyE????????tryE?????E???reg; ??行??个try???需 ??一 ???reg; ??的catch??或finally?句?一 ?????q回 ????????敎ͼ ???q?一 ?????的??常”,???q?一 ???的return?句,finally????????员函 ?q????行????一 ??子, ???????敎ͼ????????????退 出, ???了finally?句?
class FinallyDemo { static void procA( ) { try { System.out.println("inside procA"); throw new RuntimeException("demo"); } finally { System.out.println("procA's finally"); } } static void procB( ) { try { System.out.println("inside procB"); return; } finally { System.out.println("procB's finally"); } } public static void main(String args[]) { try { procA( ); } catch (Exception e); procB( ); } }
???q?????q??l?果:
C:\>java FinallyDemo inside procA procA's finally inside procB procB's finally
1. ??常????E??q??????????c?2. 在??常?c????最 ???c?叫ThrowableQ????????子类QException和Error?3. Java的??常????q??????实现QtryQcatchQthrowQthrows和finally。?br />
来自Q?a >http://www.shu.edu.cn/campus/java/chp8.html