﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>语源科技BlogJava-常言笑的家</title><link>http://www.blogjava.net/wealupa/</link><description>Spring, Hibernate, Struts, Ajax, RoR</description><language>zh-cn</language><lastBuildDate>Tue, 07 Apr 2026 12:12:10 GMT</lastBuildDate><pubDate>Tue, 07 Apr 2026 12:12:10 GMT</pubDate><ttl>60</ttl><item><title>redis cluster java client jedisCluster spring集成方法</title><link>http://www.blogjava.net/wealupa/archive/2016/08/07/431487.html</link><dc:creator>常言笑</dc:creator><author>常言笑</author><pubDate>Sun, 07 Aug 2016 09:50:00 GMT</pubDate><guid>http://www.blogjava.net/wealupa/archive/2016/08/07/431487.html</guid><wfw:comment>http://www.blogjava.net/wealupa/comments/431487.html</wfw:comment><comments>http://www.blogjava.net/wealupa/archive/2016/08/07/431487.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wealupa/comments/commentRss/431487.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wealupa/services/trackbacks/431487.html</trackback:ping><description><![CDATA[<span style="color: #232323; font-family: 'Comic Sans MS'; line-height: 25.2px; background-color: #ffffff;"><strong>1、使用jedis的原生JedisCluster<br />
<br />
</strong></span><span style="color: #232323; font-family: 'Comic Sans MS'; line-height: 25.2px; background-color: #ffffff;">spring的applicationContext.xml配置redis的连接、连接池、jedisCluster Bean<br />
</span>
<div style="font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%; word-break: break-all; background-color: #eeeeee;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000ff; font-family: 'Comic Sans MS';">&nbsp; &nbsp; &nbsp;&lt;</span><span style="color: #800000; font-family: 'Comic Sans MS';">bean&nbsp;</span><span style="color: #ff0000; font-family: 'Comic Sans MS';">id</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">="propertyConfigurer"&nbsp;</span><span style="color: #ff0000; font-family: 'Comic Sans MS';">class</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">&gt;</span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #0000ff; font-family: 'Comic Sans MS';">&lt;</span><span style="color: #800000; font-family: 'Comic Sans MS';">property&nbsp;</span><span style="color: #ff0000; font-family: 'Comic Sans MS';">name</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">="locations"</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">&gt;</span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #0000ff; font-family: 'Comic Sans MS';">&lt;</span><span style="color: #800000; font-family: 'Comic Sans MS';">list</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">&gt;</span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<span style="color: #0000ff; font-family: 'Comic Sans MS';">&lt;</span><span style="color: #800000; font-family: 'Comic Sans MS';">value</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">&gt;</span><span style="font-family: 'Comic Sans MS';">classpath:redis.properties</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">&lt;/</span><span style="color: #800000; font-family: 'Comic Sans MS';">value</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">&gt;</span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #0000ff; font-family: 'Comic Sans MS';">&lt;/</span><span style="color: #800000; font-family: 'Comic Sans MS';">list</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">&gt;</span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #0000ff; font-family: 'Comic Sans MS';">&lt;/</span><span style="color: #800000; font-family: 'Comic Sans MS';">property</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">&gt;</span><br />
<span style="color: #0000ff; font-family: 'Comic Sans MS';">&nbsp; &nbsp; &nbsp;&lt;/</span><span style="color: #800000; font-family: 'Comic Sans MS';">bean</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">&gt;<br /></span><br />
<span style="color: #008000; font-family: 'Comic Sans MS';">&nbsp; &nbsp; &nbsp;&lt;!--</span><span style="color: #008000; font-family: 'Comic Sans MS';">&nbsp;redis&nbsp;config&nbsp;start&nbsp;</span><span style="color: #008000; font-family: 'Comic Sans MS';">--&gt;</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; font-family: 'Comic Sans MS';">&lt;!--</span><span style="color: #008000; font-family: 'Comic Sans MS';">&nbsp;redis&nbsp;pool&nbsp;config&nbsp;</span><span style="color: #008000; font-family: 'Comic Sans MS';">--&gt;</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff; font-family: 'Comic Sans MS';">&lt;</span><span style="color: #800000; font-family: 'Comic Sans MS';">bean&nbsp;</span><span style="color: #ff0000; font-family: 'Comic Sans MS';">id</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">="genericObjectPoolConfig"</span><span style="color: #ff0000; font-family: 'Comic Sans MS';">&nbsp;class</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">="org.apache.commons.pool2.impl.GenericObjectPoolConfig"</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">&gt;</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff; font-family: 'Comic Sans MS';">&lt;</span><span style="color: #800000; font-family: 'Comic Sans MS';">property&nbsp;</span><span style="color: #ff0000; font-family: 'Comic Sans MS';">name</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">="maxTotal"</span><span style="color: #ff0000; font-family: 'Comic Sans MS';">&nbsp;&nbsp;value</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">="${redis.maxActive}"</span><span style="color: #FF0000; ">&nbsp;</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">/&gt;</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff; font-family: 'Comic Sans MS';">&lt;</span><span style="color: #800000; font-family: 'Comic Sans MS';">property&nbsp;</span><span style="color: #ff0000; font-family: 'Comic Sans MS';">name</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">="maxIdle"</span><span style="color: #ff0000; font-family: 'Comic Sans MS';">&nbsp;&nbsp;&nbsp;value</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">="${redis.maxIdle}"</span><span style="color: #FF0000; ">&nbsp;</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">/&gt;</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff; font-family: 'Comic Sans MS';">&lt;</span><span style="color: #800000; font-family: 'Comic Sans MS';">property&nbsp;</span><span style="color: #ff0000; font-family: 'Comic Sans MS';">name</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">="maxWaitMillis"</span><span style="color: #ff0000; font-family: 'Comic Sans MS';">&nbsp;value</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">="${redis.maxWaitMillis}"</span><span style="color: #FF0000; ">&nbsp;</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">/&gt;</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff; font-family: 'Comic Sans MS';">&lt;</span><span style="color: #800000; font-family: 'Comic Sans MS';">property&nbsp;</span><span style="color: #ff0000; font-family: 'Comic Sans MS';">name</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">="testOnBorrow"</span><span style="color: #ff0000; font-family: 'Comic Sans MS';">&nbsp;value</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">="${redis.testOnBorrow}"</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">/&gt;</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff; font-family: 'Comic Sans MS';">&lt;/</span><span style="color: #800000; font-family: 'Comic Sans MS';">bean</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">&gt;<br /></span><br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; font-family: 'Comic Sans MS';">&lt;!--</span><span style="color: #008000; font-family: 'Comic Sans MS';">&nbsp;jedisCluster&nbsp;config&nbsp;</span><span style="color: #008000; font-family: 'Comic Sans MS';">--&gt;</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff; font-family: 'Comic Sans MS';">&lt;</span><span style="color: #800000; font-family: 'Comic Sans MS';">bean&nbsp;</span><span style="color: #ff0000; font-family: 'Comic Sans MS';">id</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">="jedisCluster"</span><span style="color: #ff0000; font-family: 'Comic Sans MS';">&nbsp;class</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">="redis.clients.jedis.JedisCluster"</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">&gt;</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff; font-family: 'Comic Sans MS';">&lt;</span><span style="color: #800000; font-family: 'Comic Sans MS';">constructor-arg&nbsp;</span><span style="color: #ff0000; font-family: 'Comic Sans MS';">index</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">="0"</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">&gt;</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff; font-family: 'Comic Sans MS';">&lt;</span><span style="color: #800000; font-family: 'Comic Sans MS';">set</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">&gt;</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff; font-family: 'Comic Sans MS';">&lt;</span><span style="color: #800000; font-family: 'Comic Sans MS';">bean&nbsp;</span><span style="color: #ff0000; font-family: 'Comic Sans MS';">class</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">="redis.clients.jedis.HostAndPort"</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">&gt;</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff; font-family: 'Comic Sans MS';">&lt;</span><span style="color: #800000; font-family: 'Comic Sans MS';">constructor-arg&nbsp;</span><span style="color: #ff0000; font-family: 'Comic Sans MS';">type</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">="String"</span><span style="color: #ff0000; font-family: 'Comic Sans MS';">&nbsp;value</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">="${redis.host1}"</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">/&gt;</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff; font-family: 'Comic Sans MS';">&lt;</span><span style="color: #800000; font-family: 'Comic Sans MS';">constructor-arg&nbsp;</span><span style="color: #ff0000; font-family: 'Comic Sans MS';">type</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">="int"</span><span style="color: #ff0000; font-family: 'Comic Sans MS';">&nbsp;value</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">="${redis.port1}"</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">/&gt;</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff; font-family: 'Comic Sans MS';">&lt;/</span><span style="color: #800000; font-family: 'Comic Sans MS';">bean</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">&gt;</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff; font-family: 'Comic Sans MS';">&lt;</span><span style="color: #800000; font-family: 'Comic Sans MS';">bean&nbsp;</span><span style="color: #ff0000; font-family: 'Comic Sans MS';">class</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">="redis.clients.jedis.HostAndPort"</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">&gt;</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff; font-family: 'Comic Sans MS';">&lt;</span><span style="color: #800000; font-family: 'Comic Sans MS';">constructor-arg&nbsp;</span><span style="color: #ff0000; font-family: 'Comic Sans MS';">type</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">="String"</span><span style="color: #ff0000; font-family: 'Comic Sans MS';">&nbsp;value</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">="${redis.host2}"</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">/&gt;</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff; font-family: 'Comic Sans MS';">&lt;</span><span style="color: #800000; font-family: 'Comic Sans MS';">constructor-arg&nbsp;</span><span style="color: #ff0000; font-family: 'Comic Sans MS';">type</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">="int"</span><span style="color: #ff0000; font-family: 'Comic Sans MS';">&nbsp;value</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">="${redis.port2}"</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">/&gt;</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff; font-family: 'Comic Sans MS';">&lt;/</span><span style="color: #800000; font-family: 'Comic Sans MS';">bean</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">&gt;</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff; font-family: 'Comic Sans MS';">&lt;/</span><span style="color: #800000; font-family: 'Comic Sans MS';">set</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">&gt;</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff; font-family: 'Comic Sans MS';">&lt;/</span><span style="color: #800000; font-family: 'Comic Sans MS';">constructor-arg</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">&gt;</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff; font-family: 'Comic Sans MS';">&lt;</span><span style="color: #800000; font-family: 'Comic Sans MS';">constructor-arg&nbsp;</span><span style="color: #ff0000; font-family: 'Comic Sans MS';">index</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">="1"</span><span style="color: #ff0000; font-family: 'Comic Sans MS';">&nbsp;ref</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">="genericObjectPoolConfig"</span><span style="color: #FF0000; ">&nbsp;</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">/&gt;</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff; font-family: 'Comic Sans MS';">&lt;/</span><span style="color: #800000; font-family: 'Comic Sans MS';">bean</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">&gt;</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; font-family: 'Comic Sans MS';">&lt;!--</span><span style="color: #008000; font-family: 'Comic Sans MS';">&nbsp;redis&nbsp;config&nbsp;end&nbsp;</span><span style="color: #008000; font-family: 'Comic Sans MS';">--&gt;</span><span style="color: #008000;"><br />
</span></div>
<span style="color: #232323; font-family: 'Comic Sans MS'; line-height: 25.2px; background-color: #ffffff;">redis.</span><span style="font-family: 'Comic Sans MS'; font-size: 12px; line-height: 21.6px; white-space: pre-wrap;">properties</span><span style="color: #232323; font-family: 'Comic Sans MS'; line-height: 25.2px; background-color: #ffffff;">的配置：</span><span style="color: #232323; font-family: 'Comic Sans MS'; line-height: 25.2px; background-color: #ffffff;"><br />
</span>
<div style="font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%; word-break: break-all; background-color: #eeeeee;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="font-family: 'Comic Sans MS';">#redis&nbsp;config</span><br /><span style="font-family: 'Comic Sans MS';">
redis.maxActive=1000</span><br /><span style="font-family: 'Comic Sans MS';">
redis.maxIdle=10</span><br /><span style="font-family: 'Comic Sans MS';">
redis.maxWaitMillis=30000</span><br /><span style="font-family: 'Comic Sans MS';">
redis.testOnBorrow=true</span><br />
<br /><span style="font-family: 'Comic Sans MS';">
#redis&nbsp;host&nbsp;and&nbsp;port&nbsp;config</span><br /><span style="font-family: 'Comic Sans MS';">
redis.host1=192.168.1.2</span><br /><span style="font-family: 'Comic Sans MS';">
redis.port1=6379</span><br /><span style="font-family: 'Comic Sans MS';">
redis.host2=192.168.1.2</span><br /><span style="font-family: 'Comic Sans MS';">
redis.port2=6380</span></div>
<span style="color: #232323; font-family: Verdana, Arial, helvetica, sans-seriff; line-height: 25.2px; background-color: #ffffff;"><br /></span><span style="color: #232323; font-family: 'Comic Sans MS'; line-height: 25.2px; background-color: #ffffff;">
jedisCluster的使用：<br />
<br />
</span>
<div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="font-family: 'Comic Sans MS';">@Autowired</span><br />
<span style="color: #0000ff; font-family: 'Comic Sans MS';">private</span><span style="font-family: 'Comic Sans MS';">&nbsp;JedisCluster&nbsp;jedisClust;</span></div>
<span style="color: #232323; font-family: 'Comic Sans MS'; line-height: 25.2px; background-color: #ffffff;"><strong>2、自定义spring工厂类生产jedisCluster</strong></span>
<p style="margin-top: 10px; margin-bottom: 10px; color: #232323; font-family: Verdana, Arial, helvetica, sans-seriff; line-height: 25.2px; background-color: #ffffff;"><span style="font-family: 'Comic Sans MS';">JedisClusterFactory.java</span><br />
</p>
<div style="font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%; word-break: break-all; background-color: #eeeeee;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000ff; font-family: 'Comic Sans MS';">package</span><span style="font-family: 'Comic Sans MS';">&nbsp;com.www.core.utils;</span><br />
<br />
<span style="color: #0000ff; font-family: 'Comic Sans MS';">import</span><span style="font-family: 'Comic Sans MS';">&nbsp;java.util.HashSet;</span><br />
<span style="color: #0000ff; font-family: 'Comic Sans MS';">import</span><span style="font-family: 'Comic Sans MS';">&nbsp;java.util.Properties;</span><br />
<span style="color: #0000ff; font-family: 'Comic Sans MS';">import</span><span style="font-family: 'Comic Sans MS';">&nbsp;java.util.Set;</span><br />
<span style="color: #0000ff; font-family: 'Comic Sans MS';">import</span><span style="font-family: 'Comic Sans MS';">&nbsp;java.util.regex.Pattern;</span><br />
<br />
<span style="color: #0000ff; font-family: 'Comic Sans MS';">import</span><span style="font-family: 'Comic Sans MS';">&nbsp;org.apache.commons.pool2.impl.GenericObjectPoolConfig;</span><br />
<span style="color: #0000ff; font-family: 'Comic Sans MS';">import</span><span style="font-family: 'Comic Sans MS';">&nbsp;org.springframework.beans.factory.FactoryBean;</span><br />
<span style="color: #0000ff; font-family: 'Comic Sans MS';">import</span><span style="font-family: 'Comic Sans MS';">&nbsp;org.springframework.beans.factory.InitializingBean;</span><br />
<span style="color: #0000ff; font-family: 'Comic Sans MS';">import</span><span style="font-family: 'Comic Sans MS';">&nbsp;org.springframework.core.io.Resource;</span><br />
<br />
<span style="color: #0000ff; font-family: 'Comic Sans MS';">import</span><span style="font-family: 'Comic Sans MS';">&nbsp;redis.clients.jedis.HostAndPort;</span><br />
<span style="color: #0000ff; font-family: 'Comic Sans MS';">import</span><span style="font-family: 'Comic Sans MS';">&nbsp;redis.clients.jedis.JedisCluster;</span><br />
<br />
<span style="color: #0000ff; font-family: 'Comic Sans MS';">public</span>&nbsp;<span style="color: #0000ff; font-family: 'Comic Sans MS';">class</span><span style="font-family: 'Comic Sans MS';">&nbsp;JedisClusterFactory&nbsp;</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">implements</span><span style="font-family: 'Comic Sans MS';">&nbsp;FactoryBean&lt;JedisCluster&gt;,&nbsp;InitializingBean&nbsp;{</span><br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff; font-family: 'Comic Sans MS';">private</span><span style="font-family: 'Comic Sans MS';">&nbsp;String&nbsp;address;</span><br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff; font-family: 'Comic Sans MS';">private</span><span style="font-family: 'Comic Sans MS';">&nbsp;JedisCluster&nbsp;jedisCluster;</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff; font-family: 'Comic Sans MS';">private</span><span style="font-family: 'Comic Sans MS';">&nbsp;Integer&nbsp;timeout;</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff; font-family: 'Comic Sans MS';">private</span><span style="font-family: 'Comic Sans MS';">&nbsp;Integer&nbsp;maxRedirections;</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff; font-family: 'Comic Sans MS';">private</span><span style="font-family: 'Comic Sans MS';">&nbsp;GenericObjectPoolConfig&nbsp;genericObjectPoolConfig;</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff; font-family: 'Comic Sans MS';">private</span><span style="font-family: 'Comic Sans MS';">&nbsp;Pattern&nbsp;p&nbsp;=&nbsp;Pattern.compile("^.+[:]\\d{1,5}\\s*$");</span><br />
<br /><span style="font-family: 'Comic Sans MS';">
&nbsp;&nbsp;&nbsp;&nbsp;@Override</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff; font-family: 'Comic Sans MS';">public</span><span style="font-family: 'Comic Sans MS';">&nbsp;JedisCluster&nbsp;getObject()&nbsp;</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">throws</span><span style="font-family: 'Comic Sans MS';">&nbsp;Exception&nbsp;{</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff; font-family: 'Comic Sans MS';">return</span><span style="font-family: 'Comic Sans MS';">&nbsp;jedisCluster;</span><br /><span style="font-family: 'Comic Sans MS';">
&nbsp;&nbsp;&nbsp;&nbsp;}</span><br />
<br /><span style="font-family: 'Comic Sans MS';">
&nbsp;&nbsp;&nbsp;&nbsp;@Override</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff; font-family: 'Comic Sans MS';">public</span><span style="font-family: 'Comic Sans MS';">&nbsp;Class&lt;?&nbsp;</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">extends</span><span style="font-family: 'Comic Sans MS';">&nbsp;JedisCluster&gt;&nbsp;getObjectType()&nbsp;{</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff; font-family: 'Comic Sans MS';">return</span><span style="font-family: 'Comic Sans MS';">&nbsp;(</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">this</span><span style="font-family: 'Comic Sans MS';">.jedisCluster&nbsp;!=&nbsp;</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">null</span><span style="font-family: 'Comic Sans MS';">&nbsp;?&nbsp;</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">this</span><span style="font-family: 'Comic Sans MS';">.jedisCluster.getClass()&nbsp;:&nbsp;JedisCluster.</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">class</span><span style="font-family: 'Comic Sans MS';">);</span><br /><span style="font-family: 'Comic Sans MS';">
&nbsp;&nbsp;&nbsp;&nbsp;}</span><br />
<br /><span style="font-family: 'Comic Sans MS';">
&nbsp;&nbsp;&nbsp;&nbsp;@Override</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff; font-family: 'Comic Sans MS';">public</span>&nbsp;<span style="color: #0000ff; font-family: 'Comic Sans MS';">boolean</span><span style="font-family: 'Comic Sans MS';">&nbsp;isSingleton()&nbsp;{</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff; font-family: 'Comic Sans MS';">return</span>&nbsp;<span style="color: #0000ff; font-family: 'Comic Sans MS';">true</span><span style="font-family: 'Comic Sans MS';">;</span><br /><span style="font-family: 'Comic Sans MS';">
&nbsp;&nbsp;&nbsp;&nbsp;}</span><br />
<br />
<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff; font-family: 'Comic Sans MS';">private</span><span style="font-family: 'Comic Sans MS';">&nbsp;Set&lt;HostAndPort&gt;&nbsp;parseHostAndPort()&nbsp;</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">throws</span><span style="font-family: 'Comic Sans MS';">&nbsp;Exception&nbsp;{</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff; font-family: 'Comic Sans MS';">try</span><span style="font-family: 'Comic Sans MS';">&nbsp;{</span><br /><span style="font-family: 'Comic Sans MS';">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String[]&nbsp;addressArr=address.trim().split(",");</span><br /><span style="font-family: 'Comic Sans MS';">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Set&lt;HostAndPort&gt;&nbsp;haps&nbsp;=&nbsp;</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">new</span><span style="font-family: 'Comic Sans MS';">&nbsp;HashSet&lt;HostAndPort&gt;();</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff; font-family: 'Comic Sans MS';">for</span><span style="font-family: 'Comic Sans MS';">(String&nbsp;addressStr:addressArr){</span><br /><span style="font-family: 'Comic Sans MS';">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String[]&nbsp;ipAndPort&nbsp;=&nbsp;addressStr.trim().split(":");</span><br /><span style="font-family: 'Comic Sans MS';">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;HostAndPort&nbsp;hap&nbsp;=&nbsp;</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">new</span><span style="font-family: 'Comic Sans MS';">&nbsp;HostAndPort(ipAndPort[0].trim(),&nbsp;Integer.parseInt(ipAndPort[1].trim()));</span><br /><span style="font-family: 'Comic Sans MS';">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;haps.add(hap);</span><br /><span style="font-family: 'Comic Sans MS';">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff; font-family: 'Comic Sans MS';">return</span><span style="font-family: 'Comic Sans MS';">&nbsp;haps;</span><br /><span style="font-family: 'Comic Sans MS';">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">catch</span><span style="font-family: 'Comic Sans MS';">&nbsp;(IllegalArgumentException&nbsp;ex)&nbsp;{</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff; font-family: 'Comic Sans MS';">throw</span><span style="font-family: 'Comic Sans MS';">&nbsp;ex;</span><br /><span style="font-family: 'Comic Sans MS';">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">catch</span><span style="font-family: 'Comic Sans MS';">&nbsp;(Exception&nbsp;ex)&nbsp;{</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff; font-family: 'Comic Sans MS';">throw</span>&nbsp;<span style="color: #0000ff; font-family: 'Comic Sans MS';">new</span><span style="font-family: 'Comic Sans MS';">&nbsp;Exception("解析&nbsp;jedis&nbsp;配置文件失败",&nbsp;ex);</span><br /><span style="font-family: 'Comic Sans MS';">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span><br /><span style="font-family: 'Comic Sans MS';">
&nbsp;&nbsp;&nbsp;&nbsp;}</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;<br /><span style="font-family: 'Comic Sans MS';">
&nbsp;&nbsp;&nbsp;&nbsp;@Override</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff; font-family: 'Comic Sans MS';">public</span>&nbsp;<span style="color: #0000ff; font-family: 'Comic Sans MS';">void</span><span style="font-family: 'Comic Sans MS';">&nbsp;afterPropertiesSet()&nbsp;</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">throws</span><span style="font-family: 'Comic Sans MS';">&nbsp;Exception&nbsp;{</span><br /><span style="font-family: 'Comic Sans MS';">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Set&lt;HostAndPort&gt;&nbsp;haps&nbsp;=&nbsp;</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">this</span><span style="font-family: 'Comic Sans MS';">.parseHostAndPort();</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br /><span style="font-family: 'Comic Sans MS';">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jedisCluster&nbsp;=&nbsp;</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">new</span><span style="font-family: 'Comic Sans MS';">&nbsp;JedisCluster(haps,&nbsp;timeout,&nbsp;maxRedirections,genericObjectPoolConfig);</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br /><span style="font-family: 'Comic Sans MS';">
&nbsp;&nbsp;&nbsp;&nbsp;}</span><br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff; font-family: 'Comic Sans MS';">public</span>&nbsp;<span style="color: #0000ff; font-family: 'Comic Sans MS';">void</span><span style="font-family: 'Comic Sans MS';">&nbsp;setTimeout(</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">int</span><span style="font-family: 'Comic Sans MS';">&nbsp;timeout)&nbsp;{</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff; font-family: 'Comic Sans MS';">this</span><span style="font-family: 'Comic Sans MS';">.timeout&nbsp;=&nbsp;timeout;</span><br /><span style="font-family: 'Comic Sans MS';">
&nbsp;&nbsp;&nbsp;&nbsp;}</span><br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff; font-family: 'Comic Sans MS';">public</span>&nbsp;<span style="color: #0000ff; font-family: 'Comic Sans MS';">void</span><span style="font-family: 'Comic Sans MS';">&nbsp;setMaxRedirections(</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">int</span><span style="font-family: 'Comic Sans MS';">&nbsp;maxRedirections)&nbsp;{</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff; font-family: 'Comic Sans MS';">this</span><span style="font-family: 'Comic Sans MS';">.maxRedirections&nbsp;=&nbsp;maxRedirections;</span><br /><span style="font-family: 'Comic Sans MS';">
&nbsp;&nbsp;&nbsp;&nbsp;}</span><br />
<br />
<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; font-family: 'Comic Sans MS';">/**</span><span style="color: #008000; "><br /></span><span style="color: #008000; font-family: 'Comic Sans MS';">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@Param&nbsp;String&nbsp;address&nbsp;to&nbsp;set<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; font-family: 'Comic Sans MS';">*/</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff; font-family: 'Comic Sans MS';">public</span>&nbsp;<span style="color: #0000ff; font-family: 'Comic Sans MS';">void</span><span style="font-family: 'Comic Sans MS';">&nbsp;setAddress(String&nbsp;address)&nbsp;{</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff; font-family: 'Comic Sans MS';">this</span><span style="font-family: 'Comic Sans MS';">.address&nbsp;=&nbsp;address;</span><br /><span style="font-family: 'Comic Sans MS';">
&nbsp;&nbsp;&nbsp;&nbsp;}</span><br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff; font-family: 'Comic Sans MS';">public</span>&nbsp;<span style="color: #0000ff; font-family: 'Comic Sans MS';">void</span><span style="font-family: 'Comic Sans MS';">&nbsp;setGenericObjectPoolConfig(GenericObjectPoolConfig&nbsp;genericObjectPoolConfig)&nbsp;{</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff; font-family: 'Comic Sans MS';">this</span><span style="font-family: 'Comic Sans MS';">.genericObjectPoolConfig&nbsp;=&nbsp;genericObjectPoolConfig;</span><br /><span style="font-family: 'Comic Sans MS';">
&nbsp;&nbsp;&nbsp;&nbsp;}</span><br />
<br /><span style="font-family: 'Comic Sans MS';">
}</span></div>
<span style="color: #232323; font-family: 'Comic Sans MS'; line-height: 25.2px; background-color: #ffffff;">spring的applicationContext.xml配置redis的连接池和工厂bean<br />
</span>
<div style="font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%; word-break: break-all; background-color: #eeeeee;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->&nbsp;<span style="color: #008000; font-family: 'Comic Sans MS';">&lt;!--</span><span style="color: #008000; font-family: 'Comic Sans MS';">&nbsp;redis连接配置&nbsp;start</span><span style="color: #008000; font-family: 'Comic Sans MS';">--&gt;</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff; font-family: 'Comic Sans MS';">&lt;</span><span style="color: #800000; font-family: 'Comic Sans MS';">bean&nbsp;</span><span style="color: #ff0000; font-family: 'Comic Sans MS';">name</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">="genericObjectPoolConfig"</span><span style="color: #ff0000; font-family: 'Comic Sans MS';">&nbsp;class</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">="org.apache.commons.pool2.impl.GenericObjectPoolConfig"</span><span style="color: #FF0000; ">&nbsp;</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">&gt;</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff; font-family: 'Comic Sans MS';">&lt;</span><span style="color: #800000; font-family: 'Comic Sans MS';">property&nbsp;</span><span style="color: #ff0000; font-family: 'Comic Sans MS';">name</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">="maxIdle"</span><span style="color: #ff0000; font-family: 'Comic Sans MS';">&nbsp;value</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">="${redis.maxIdle}"</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">/&gt;</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff; font-family: 'Comic Sans MS';">&lt;</span><span style="color: #800000; font-family: 'Comic Sans MS';">property&nbsp;</span><span style="color: #ff0000; font-family: 'Comic Sans MS';">name</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">="maxTotal"</span><span style="color: #ff0000; font-family: 'Comic Sans MS';">&nbsp;value</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">="${redis.maxTotal}"</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">/&gt;</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff; font-family: 'Comic Sans MS';">&lt;</span><span style="color: #800000; font-family: 'Comic Sans MS';">property&nbsp;</span><span style="color: #ff0000; font-family: 'Comic Sans MS';">name</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">="minIdle"</span><span style="color: #ff0000; font-family: 'Comic Sans MS';">&nbsp;value</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">="${redis.minIdle}"</span><span style="color: #FF0000; ">&nbsp;</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">/&gt;</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff; font-family: 'Comic Sans MS';">&lt;/</span><span style="color: #800000; font-family: 'Comic Sans MS';">bean</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">&gt;</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; font-family: 'Comic Sans MS';">&lt;!--</span><span style="color: #008000; font-family: 'Comic Sans MS';">&nbsp;redis连接配置&nbsp;end</span><span style="color: #008000; font-family: 'Comic Sans MS';">--&gt;</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff; font-family: 'Comic Sans MS';">&lt;</span><span style="color: #800000; font-family: 'Comic Sans MS';">bean&nbsp;</span><span style="color: #ff0000; font-family: 'Comic Sans MS';">id</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">="jedisCluster"</span><span style="color: #ff0000; font-family: 'Comic Sans MS';">&nbsp;class</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">="com.www.core.utils.JedisClusterFactory"</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">&gt;</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff; font-family: 'Comic Sans MS';">&lt;</span><span style="color: #800000; font-family: 'Comic Sans MS';">property&nbsp;</span><span style="color: #ff0000; font-family: 'Comic Sans MS';">name</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">="address"</span><span style="color: #ff0000; font-family: 'Comic Sans MS';">&nbsp;value</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">="${redis.adress}"</span><span style="color: #FF0000; ">&nbsp;</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">/&gt;</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff; font-family: 'Comic Sans MS';">&lt;</span><span style="color: #800000; font-family: 'Comic Sans MS';">property&nbsp;</span><span style="color: #ff0000; font-family: 'Comic Sans MS';">name</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">="timeout"</span><span style="color: #ff0000; font-family: 'Comic Sans MS';">&nbsp;value</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">="${redis.timeout}"</span><span style="color: #FF0000; ">&nbsp;</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">/&gt;</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff; font-family: 'Comic Sans MS';">&lt;</span><span style="color: #800000; font-family: 'Comic Sans MS';">property&nbsp;</span><span style="color: #ff0000; font-family: 'Comic Sans MS';">name</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">="maxRedirections"</span><span style="color: #ff0000; font-family: 'Comic Sans MS';">&nbsp;value</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">="${redis.maxRedirections}"</span><span style="color: #FF0000; ">&nbsp;&nbsp;</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">/&gt;</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff; font-family: 'Comic Sans MS';">&lt;</span><span style="color: #800000; font-family: 'Comic Sans MS';">property&nbsp;</span><span style="color: #ff0000; font-family: 'Comic Sans MS';">name</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">="genericObjectPoolConfig"</span><span style="color: #ff0000; font-family: 'Comic Sans MS';">&nbsp;ref</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">="genericObjectPoolConfig"</span><span style="color: #FF0000; ">&nbsp;</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">/&gt;</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff; font-family: 'Comic Sans MS';">&lt;/</span><span style="color: #800000; font-family: 'Comic Sans MS';">bean</span><span style="color: #0000ff; font-family: 'Comic Sans MS';">&gt;</span></div>
<span style="color: #232323; font-family: 'Comic Sans MS'; line-height: 25.2px; background-color: #ffffff;">redis.</span><span style="font-family: 'Comic Sans MS'; font-size: 12px; line-height: 21.6px; white-space: pre-wrap;">properties</span><span style="color: #232323; font-family: 'Comic Sans MS'; line-height: 25.2px; background-color: #ffffff;">配置</span><span style="color: #232323; font-family: 'Comic Sans MS'; line-height: 25.2px; background-color: #ffffff;"><br />
</span>
<div style="font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%; word-break: break-all; background-color: #eeeeee;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="font-family: 'Comic Sans MS';">#redis&nbsp;config</span><br /><span style="font-family: 'Comic Sans MS';">
redis.maxTotal=200</span><br /><span style="font-family: 'Comic Sans MS';">
redis.maxIdle=50</span><br /><span style="font-family: 'Comic Sans MS';">
redis.minIdle=10</span><br />
<br /><span style="font-family: 'Comic Sans MS';">
#redis&nbsp;host&nbsp;and&nbsp;port&nbsp;config</span><br /><span style="font-family: 'Comic Sans MS';">
redis.adress=192.168.1.2:6379,192.168.1.2:6380,192.168.1.2:6381</span><br /><span style="font-family: 'Comic Sans MS';">
redis.timeout=300000</span><br /><span style="font-family: 'Comic Sans MS';">
redis.maxRedirections=6</span></div>
<br /><span style="font-family: 'Comic Sans MS';">jedisCluster的使用：</span><br /><br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="font-family: 'Comic Sans MS';">@Autowired</span><br /><span style="color: #0000ff; font-family: 'Comic Sans MS';">private</span><span style="font-family: 'Comic Sans MS';">&nbsp;JedisCluster&nbsp;jedisCluster;</span></div><img src ="http://www.blogjava.net/wealupa/aggbug/431487.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wealupa/" target="_blank">常言笑</a> 2016-08-07 17:50 <a href="http://www.blogjava.net/wealupa/archive/2016/08/07/431487.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Redis 3.X版本引入了集群的新特性的三种用法</title><link>http://www.blogjava.net/wealupa/archive/2016/08/07/431486.html</link><dc:creator>常言笑</dc:creator><author>常言笑</author><pubDate>Sun, 07 Aug 2016 09:32:00 GMT</pubDate><guid>http://www.blogjava.net/wealupa/archive/2016/08/07/431486.html</guid><wfw:comment>http://www.blogjava.net/wealupa/comments/431486.html</wfw:comment><comments>http://www.blogjava.net/wealupa/archive/2016/08/07/431486.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wealupa/comments/commentRss/431486.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wealupa/services/trackbacks/431486.html</trackback:ping><description><![CDATA[<strong style="margin: 0px; padding: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; background-color: #ffffff;">一、利用Jedis来实现<br /></strong><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;"><span style="margin: 0px; padding: 0px; font-size: 13px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Set&lt;HostAndPort&gt;&nbsp; jedisClusterNodes = new HashSet&lt;HostAndPort&gt;();</span></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;"><span style="margin: 0px; padding: 0px; font-size: 13px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //Jedis Cluster will attempt to discover cluster nodes automatically</span></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;"><span style="margin: 0px; padding: 0px; font-size: 13px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jedisClusterNodes.add(new HostAndPort("10.96.5.183",9001));</span></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;"><span style="margin: 0px; padding: 0px; font-size: 13px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; jedisClusterNodes.add(new HostAndPort("10.96.5.183",9002));</span></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;"><span style="margin: 0px; padding: 0px; font-size: 13px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;jedisClusterNodes.add(new HostAndPort("10.96.5.183",9003));</span></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;"><span style="margin: 0px; padding: 0px; font-size: 13px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;JedisCluster jc = new JedisCluster(jedisClusterNodes);<br /><br /><strong style="margin: 0px; padding: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 14px; background-color: #ffffff;">二、利用spring-data-redis来实现<br /></strong></span></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; background-color: #ffffff;">&nbsp; &nbsp; &nbsp;&lt;!--通过构造方法注入RedisNode--&gt;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; background-color: #ffffff;">&nbsp; &nbsp; &nbsp;<span style="margin: 0px; padding: 0px; font-size: 13px;">&lt;bean id="clusterRedisNodes1"&nbsp;&nbsp; class="<em style="margin: 0px; padding: 0px;">org.springframework.data.redis.connection.RedisNode</em>"&gt;&nbsp;</span></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; background-color: #ffffff;"><span style="margin: 0px; padding: 0px; font-size: 13px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;constructor-arg value="10.96.5.183" /&gt;</span></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; background-color: #ffffff;"><span style="margin: 0px; padding: 0px; font-size: 13px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;constructor-arg value="9002" type="int" /&gt;</span></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; background-color: #ffffff;"><span style="margin: 0px; padding: 0px; font-size: 13px;">&nbsp;&nbsp;&nbsp;&nbsp; &lt;/bean&gt;</span></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; background-color: #ffffff;"><span style="margin: 0px; padding: 0px; font-size: 13px;">&nbsp;&nbsp;&nbsp;&nbsp; ....</span></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; background-color: #ffffff;"><span style="margin: 0px; padding: 0px; font-size: 13px;">&nbsp;&nbsp;&nbsp; &lt;!--setter方式注入--&gt;</span></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; background-color: #ffffff;"><span style="margin: 0px; padding: 0px; font-size: 13px;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="margin: 0px; padding: 0px;">&lt;bean id="redisClusterConfiguration"&nbsp;&nbsp; class="<em style="margin: 0px; padding: 0px;">org.springframework.data.redis.connection.RedisClusterConfiguration</em>"&gt;</span></span></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; background-color: #ffffff;"><span style="margin: 0px; padding: 0px; font-size: 13px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="<span style="margin: 0px; padding: 0px;">clusterNodes</span>"&gt;</span></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; background-color: #ffffff;"><span style="margin: 0px; padding: 0px; font-size: 13px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;set&gt;</span></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; background-color: #ffffff;"><span style="margin: 0px; padding: 0px; font-size: 13px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;ref bean="clusterRedisNodes1"/&gt;</span></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; background-color: #ffffff;"><span style="margin: 0px; padding: 0px; font-size: 13px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;ref bean="clusterRedisNodes2"/&gt;</span></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; background-color: #ffffff;"><span style="margin: 0px; padding: 0px; font-size: 13px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;ref bean="clusterRedisNodes3"/&gt;</span></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; background-color: #ffffff;"><span style="margin: 0px; padding: 0px; font-size: 13px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/set&gt;</span></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; background-color: #ffffff;"><span style="margin: 0px; padding: 0px; font-size: 13px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/property&gt;<br /><span style="line-height: 19.5px;">&nbsp; &nbsp; &lt;/bean&gt;</span><br /></span></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; background-color: #ffffff;"><span style="margin: 0px; padding: 0px; font-size: 13px;">&nbsp; &lt;!--setter方式注入,对应的属性需存在setterXXX方法--&gt;</span></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; background-color: #ffffff;"><span style="margin: 0px; padding: 0px; font-size: 13px;"><br /></span></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; background-color: #ffffff;"><span style="margin: 0px; padding: 0px; font-size: 13px;">&nbsp; &nbsp;<span style="margin: 0px; padding: 0px;">&lt;bean id="jedisPoolConfig"&nbsp;&nbsp; class="redis.clients.jedis.JedisPoolConfig"&gt;</span></span></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; background-color: #ffffff;"><span style="margin: 0px; padding: 0px; font-size: 13px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="maxToal" value="1000" /&gt;</span></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; background-color: #ffffff;"><span style="margin: 0px; padding: 0px; font-size: 13px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &lt;property name="maxIdle" value="1000" /&gt;</span></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; background-color: #ffffff;"><span style="margin: 0px; padding: 0px; font-size: 13px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&lt;property name="maxWaitMillis" value="1000" /&gt;</span></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; background-color: #ffffff;"><span style="margin: 0px; padding: 0px; font-size: 13px;">&nbsp;&nbsp; &lt;/bean&gt;</span></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; background-color: #ffffff;"><span style="margin: 0px; padding: 0px; font-size: 13px;">&nbsp; &lt;bean id="jedisConnFactory"&nbsp;&nbsp; class="<em style="margin: 0px; padding: 0px;">org.springframework.data.redis.connection.jedis.JedisConnectionFactory</em>" p:use-pool="true"&gt;</span></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; background-color: #ffffff;"><span style="margin: 0px; padding: 0px; font-size: 13px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;constructor-arg ref="redisClusterConfiguration" /&gt;</span></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; background-color: #ffffff;"><span style="margin: 0px; padding: 0px; font-size: 13px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;constructor-arg ref="jedisPoolConfig" /&gt;</span></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; background-color: #ffffff;"><span style="margin: 0px; padding: 0px; font-size: 13px;">&nbsp;&nbsp;&lt;/bean&gt;</span></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; background-color: #ffffff;"><span style="margin: 0px; padding: 0px; font-size: 13px;">&nbsp;&lt;bean id="redisTemplate"&nbsp;&nbsp; class="<em style="margin: 0px; padding: 0px;">org.springframework.data.redis.core.RedisTemplate</em>"&nbsp;&nbsp;</span><span style="margin: 0px; padding: 0px; font-size: 13px;">p:connection-factory-ref="jedisConnFactory" /&gt;</span></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; background-color: #ffffff;"><span style="margin: 0px; padding: 0px; font-size: 13px;">&lt;!--setter方式注入PersonRepoImpl--&gt;</span></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; background-color: #ffffff;"><span style="margin: 0px; padding: 0px; color: #ff00ff; font-size: 13px;">&lt;bean id="<strong style="margin: 0px; padding: 0px;"><em style="margin: 0px; padding: 0px;">personRepo</em></strong>"&nbsp; class="<em style="margin: 0px; padding: 0px;"><strong style="margin: 0px; padding: 0px;">com.example.repo.impl.PersonRepoImpl</strong></em>"&gt;</span></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; background-color: #ffffff;"><span style="margin: 0px; padding: 0px; color: #ff00ff; font-size: 13px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="redisTemplate" ref="redisTemplate" /&gt;</span></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; background-color: #ffffff;"><span style="margin: 0px; padding: 0px; color: #ff00ff; font-size: 13px;">&lt;/bean&gt;<br /><br /></span></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; background-color: #ffffff;"><strong style="margin: 0px; padding: 0px;">三、简单集成Spring</strong></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; background-color: #ffffff;"><span style="margin: 0px; padding: 0px; color: #ff00ff; font-size: 13px;"></span></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; background-color: #ffffff;"><strong style="margin: 0px; padding: 0px;">&nbsp; &nbsp;&nbsp;</strong>自己编写jedisCluster的工厂类JedisClusterFactory,然后通过Spring注入的方式获取jedisCluster,实现客户端使用Redis3.0版本的集群特性。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;"><span style="margin: 0px; padding: 0px; font-size: 13px;"><strong style="margin: 0px; padding: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 14px; background-color: #ffffff;"></strong></span></p><img src ="http://www.blogjava.net/wealupa/aggbug/431486.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wealupa/" target="_blank">常言笑</a> 2016-08-07 17:32 <a href="http://www.blogjava.net/wealupa/archive/2016/08/07/431486.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Perl、PHP、Python、Java和Ruby的比较</title><link>http://www.blogjava.net/wealupa/archive/2012/06/28/381724.html</link><dc:creator>常言笑</dc:creator><author>常言笑</author><pubDate>Thu, 28 Jun 2012 07:41:00 GMT</pubDate><guid>http://www.blogjava.net/wealupa/archive/2012/06/28/381724.html</guid><wfw:comment>http://www.blogjava.net/wealupa/comments/381724.html</wfw:comment><comments>http://www.blogjava.net/wealupa/archive/2012/06/28/381724.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wealupa/comments/commentRss/381724.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wealupa/services/trackbacks/381724.html</trackback:ping><description><![CDATA[<div>提问<br /><br />&#9670; Perl、Python、Ruby和PHP各自有何特点?<br /><br />&#9670; 为什么动态语言多作为轻量级的解决方案?<br /><br />&#9670; LAMP为什么受欢迎?<br /><br />&#9670; Ruby on Rails为什么会流行?<br /><br />&#9670; 编程语言的发展趋势是什么?<br /><br />讲解<br /><br />&#8220;剩下四种动态语言，我们将之归为后台脚本语言。&#8221;冒号说着画了张图表&#8212;&#8212;<br /><br /><br /><br />引号听得仔细：&#8220;我记得您开始是把这些语言划分为C族静态语言、非C族静态语言和动态语言三类的。&#8221;<br /><br />冒号解释：&#8220;那是按语法来划分的，偏重理论;现在是按应用来划分，偏重实践。&#8221;<br /><br />句号旋即联想到：&#8220;这种分法貌似三层架构&#8212;&#8212;前台语言对应表现层;平台语言和后台脚本语言对应业务逻辑层;系统语言对应数据层。&#8221;<br /><br />&#8220;的 确有几分神似，但千万不可混淆。&#8221;冒号提醒道，&#8220;三层架构(three-layer  architecture)是模块设计上的逻辑划分[1];而这里是按语言应用范围进行的物理划分&#8212;&#8212;与用户交互的是前台语言，与机器交互的是系统语言， 介于其中的为前台提供服务同时又需要底层系统服务的是后台语言。&#8221;<br /><br />逗号询问：&#8220;后台语言又细分成平台语言与后台脚本语言?&#8221;<br /><br />&#8220;这 是基于程序(program)与脚本(script)、静态与动态而分的。&#8221;冒号进行说明，&#8220;其实Perl，PHP，Python和Ruby都有自己的虚 拟机(virtual  machine)，从这种意义上说它们也可作为平台语言。但在实际应用中，它们没有Java平台和.NET平台那种整合凝聚力和核心作用，通常作为轻量级 的解决方案。&#8221;<br /><br />问号想探个究竟：&#8220;这是由于它们都是动态语言的缘故吗?&#8221;<br /><br />冒号回答：&#8220;理论上动态语言同样能承担大型应 用，但实践上它们多作为粘合语言或用于中小型应用。用句时髦的话来形容，暂时还是主流的配角或非主流的主角。毕竟在运行效率、类型安全、可用资源、开发工 具、技术支持等方面，它们与Java、C#相比尚有一定差距。另外它们同属&#8216;草根&#8217;语言，虽有开源社区的大力支持，在影响力上与后者未可同日而语。&#8221;<br /><br />叹号揣测：&#8220;说不定在不久的将来，动态语言也会成为主流的主角。&#8221;<br /><br />&#8220;世 易时移，殊难逆料。但有一点可以肯定，语言的发展趋势一定是动静结合、刚柔并济。&#8221;冒号断言，&#8220;一方面以Java和C#为代表的静态语言中嫁接了动态语言 的枝条;另一方面以Java和.NET为代表的平台与动态语言的交壤地带也在逐步扩大。比如JRuby允许Ruby与Java之间互相调用，类似的还有 Jython、IronRuby、IronPython等等。此外值得一提的是，动态语言最活跃的舞台当数LAMP，L-A-M-P。&#8221;<br /><br />引号接茬：&#8220;L是Linux，A是Apache，M是MySQL，P是PHP。这四大组件形成了一个完整的开源网络开发平台。&#8221;<br /><br />冒号补充道：&#8220;P也可指Perl、Python，甚至Ruby。&#8221;<br /><br />逗号调侃：&#8220;可惜Ruby的&#8216;R&#8217;比&#8216;P&#8217;多了一根尾巴。&#8221;<br /><br />&#8220;有 人为了自圆其说，干脆让P表示&#8216;Programming  language&#8217;，这下所有语言都囊括其中了。老外就喜欢玩这种首字母缩略(acronym)的文字游戏，尤其LAMP正好还有&#8216;灯&#8217;的含义，寓意开源 世界的一盏明灯，他们一定更得意了。&#8221;冒号语带调笑，&#8220;前面我们曾提及，网络应用是生长动态语言最肥沃的土壤，而LAMP就是这块土壤上搭建的平台。作为 网络平台，LAMP以其开放灵活、开发迅速、部署方便、高可配置、安全可靠、成本低廉等特色而与Java平台和.NET平台鼎足三分，尤其受中小企业的欢 迎。LAMP中Linux是操作系统，Apache是Web服务器，MySQL是数据库系统，而我们当下最关心的是&#8216;P族语言&#8217;：PHP、Perl、 Python还有Ruby。&#8221;<br /><br />问号建议：&#8220;作为动态语言，它们的共性上节课已经谈了不少，能说说它们的个性吗?&#8221;<br /><br />&#8220;它们 的个性极为鲜明：Perl凝练晦涩，Python优雅明晰，Ruby精巧灵动，PHP简明单纯。先看老大哥Perl，它博采众家之长，综合了C语言的结 构、sed的正则表达式、AWK的关联数组(associative array)、Lisp的表(list)和Unix  Shell的命令，此外还有借鉴了一种语言，你们知道是哪种吗?&#8221;冒号忽然卖了个关子。<br /><br />逗号猜想：&#8220;应该是某种OOP语言吧。&#8221;<br /><br />&#8220;Perl 中确有不少C++的影子，但它的对象模型在5.0以后才引入，典型的半路出家，远不如前面的特征那么自然。与其说是一种自然而然的发展，不如说是在OOP 潮流裹挟下的一种身不由己的迎合。真正深入骨髓的借鉴是自然语言。&#8221;冒号给出了答案，&#8220;我们提过，Perl的发明者Larry  Wall是一名语言学家，他认为程序语言应该与自然语言一样，简洁自然、易读易写、表达多样、不拘一格。Perl还有不少的格言或哲学，使得编程语言一改 严谨刻板的面孔，散发出浓郁的人文气息。&#8221;<br /><br />叹号幽了一默：&#8220;我见过Perl的代码，人文气息没闻出来，但我怀疑有乙醚气息&#8212;&#8212;看一会就觉得晕晕乎乎的。&#8221;<br /><br />众人大笑。<br /><br />&#8220;有 人仅用一行Perl代码就实现了RSA算法，你看了那还不得当场晕倒啊?&#8221;冒号打趣道，&#8220;Perl的各种魔符好似一把把锋利的剪刀，做起文本裁剪之类的工 作来游刃有余。这是它最大的长处，当初Perl就是Wall用来做Unix系统管理的，以后在CGI上的广泛应用也得益于此。这也赋予Perl极强的粘合 力，因而有&#8216;internet上的胶带(duct  tape)[2]&#8217;的说法。它又号称瑞士军刀，精练而复杂，实用而强大。但Perl过于灵活自由，缺乏规范，影响了程序的可读性、一致性、整洁性和可维护 性。不熟悉该语言的固然如读天书，熟悉语言而不熟悉问题的也颇费思量。相比之下Python被认为是Perl有力的挑战者，不仅在于它天然的OO设计和丰 富的类库，更重要的是它对程序员友好度大大超过Perl。Python也有一系列的被称为禅(Zen)的哲学，不少与Perl是针锋相对的。比 如：Perl认为做一件事可以有多种方法，而Python认为一件事应该最好只有一种方法;Perl追求语言的表现力，Python追求简单优 雅;Perl喜欢隐性暗示，Python强调显性明示;Perl强调紧凑，Python强调松散;  Perl的语法和语义丰富，Python的语法和语义简单而类库丰富。或许Python最让人不习惯的是它对空白符敏感性。&#8221;<br /><br />引号感到惊奇：&#8220;对空白符敏感?这个倒真怪异。&#8221;<br /><br />冒 号见惯不怪：&#8220;虽然有点违反习惯，但非常符合Python一贯的规范简洁的风格&#8212;&#8212;一方面从语法上保证了良好的编码风格;另一方面，每个代码块不再需要起 始的大括号或begin/end之类的，减少了的代码行数。顺便插一句，另外一种优雅的语言Haskell同样对空白符敏感，或许优雅正是来自对细节和规 范的重视吧。此外许多人抱怨Python中的自引用self太多，殊不知这也是它倡导显式表达的一种体现。总的看来，Python主要的问题还是在性能效 率上不尽如人意。&#8221;<br /><br />叹号好奇地问：&#8220;Ruby怎么样?据说它将取代Java。&#8221;<br /><br />&#8220;不要轻言&#8216;取代&#8217;二字。&#8221;冒号规诫 道，&#8220;Java没有取代C++，也不会被Ruby取代，至多只是一种再分配。不过Ruby的确是门很可爱的语言，兼具Perl的表现力和Python的可 读性。Ruby背后最具特色的理念是：关注程序员使用语言时的感受超过语言本身的功能。通俗地说，兵器的称手比锋利更重要;文雅地说，应给予程序员更多的 人文关怀。就拿代码块(block)和迭代器(iterator)来说，虽然均非Ruby首创，但其语法最为赏心悦目。类似的例子比比皆是。Ruby的元 编程能力特别强，也是它高度灵活的一种体现，但并不是所有人都喜欢这种风格。Ruby的主要弱点有两个：一个与Python类似，在性能上还有待提高;另 一个是它的线程由用户空间(user space)而不是内核空间(kernel  space)来管理[3]，不能充分利用多核或多CPU。真正让Ruby变得炙手可热的是web应用框架 Ruby on  Rails(RoR)的成功，它们还催生了Java平台上的Groovy语言和Groovy on  Grails框架。RoR奉行的CoC(Convention over Configuration)和DRY(Don&#8217;t repeat  yourself )原则以及MVC架构看似了无新意，但与Ruby结合之后，便如一只猱身而上灵猫，立刻衬托出Java和.NET大象般的身影。&#8221;<br /><br />逗号有些怀疑：&#8220;框架竟然捧红了语言，框架真有这么重要吗?&#8221;<br /><br />&#8220;如 果web应用中动态页面较少或业务逻辑不复杂，框架的价值并不大。以前CGI编程就是往Perl之类的代码中嵌入HTML代码，如同Java中的 Servlet;PHP则单纯地在HTML代码中插入PHP代码，如同早期的JSP。没有MVC，也不管什么三层架构，更没有ORM。但是&#8212;&#8212;&#8221;冒号拖了 个转折音，&#8220;一旦业务逻辑变得复杂，开发人员增多，手工作坊式编程开始捉襟见肘，引入框架这个流水生产线来提高生产力便是大势所趋。&#8221;<br /><br />句号不解：&#8220;我想Perl、Python和PHP一定也有不少框架，Java中的框架更是泛滥成灾，何以独独RoR脱颖而出?&#8221;<br /><br />冒 号作出分析：&#8220;正值web2.0和敏捷开发(agile  development)的概念流行之际，RoR将AJAX与Ruby组合在一起成为绝佳的回应。以前各种web应用框架是不少，但在RoR之前轻量级套 餐式解决方案并不多。Perl中的Catalyst、Python中的Pylon还有PHP中的CakePHP等应是效仿之作。因此RoR出现的时机可说 是不早不晚，正当其时。此外，Perl和PHP由于过于流行，反而有不少的历史包袱，人们习惯了将表示逻辑和业务逻辑编织在一起。至于Java企业解决方 案，框架太多，搭配组合更多，增加了选择的难度。即使采用最常见的轻量级SSH(Struts+Spring+Hibernate)组合，维护起来也比 RoR繁杂得多。&#8221;<br /><br />叹号愈发担忧：&#8220;听这意思，Java还是危险啊!&#8221;<br /><br />&#8220;言之过早。&#8221;冒号不以为然，&#8220;首先RoR还有待进一步检验，目前无论是应用广度还是深度上尚无法与Java相提并论;其次Java在性能、安全等方面还是有不少优势，而这些对于大型和关键性的应用来说尤为重要。即使在中小型web应用中，RoR较之PHP还远为不及。&#8221;<br /><br />问号接下话题：&#8220;PHP为何如此流行?&#8221;<br /><br />&#8220;因 为它简单、专一。&#8221;冒号答得很干脆，&#8220;与Python和Ruby一开始就定位通用语言不同，PHP是专为网络而生的。同早期的Perl相似，PHP起初主 要起文本过滤器的作用，只不过Perl多处理文件流(file stream)，而PHP多处理套接字流(socket  stream)。PHP的语法简单，且为网络应用度身定造，受到网络开发人员的追捧当在情理之中。它虽很实用很流行，但并不完美。比如：变量名大小写敏感 而函数名大小写不敏感;函数命名规则不一致;不支持namespace和unicode[4];与Perl一样，它的对象模型不是先天的，直到PHP  5才真正完善;对线程支持不足;相比Perl、Python和Ruby，它的功能稍显单薄等等。&#8221;<br /><br />引号突然想起：&#8220;我记得您在第一堂课提到PHP还能用于桌面应用。&#8221;<br /><br />&#8220;不 仅PHP，Perl、Python还有Ruby，都能作为前台语言来开发命令行或图形界面的应用。同样地，VB、Delphi和JavaScript也能 作为后台语言。现代的程序语言既有自己的专长，又向通用化和全能化发展，以争取更多的生存空间。试想一下，现代的程序员又何尝不是如此呢?&#8221;言及于此，冒 号收住话题，&#8220;语言简评告一段落，还有不少既有趣又有用的语言，在此就不一一评说了。我们看到，每种编程语言都有其独特的惯例用法和哲学理念，它们与编程 范式一道形成了语言的编程风格。体悟愈深者编程语感愈强，思维与语言愈交融无碍，渐从必然王国走向自由王国。&#8221;<br /><br />逗号满怀憧憬：&#8220;那是不是一种人剑合一的境界?&#8221;<br /><br />&#8220;或许人器合一更准确吧，程序员可不能只会一种兵器哟。&#8221;冒号故意抠他的字眼，&#8220;现在请大家每人写一句对本节课的感言。&#8221;<br /><br />众人沉思片刻，齐齐挥笔而就&#8212;&#8212;<br /><br />叹号&#8212;&#8212;没有最好的语言，只有最合适的语言。<br /><br />逗号&#8212;&#8212;没有糟糕的语言，只有糟糕的程序员。<br /><br />问号&#8212;&#8212;没有一种语言是万能的，只会一种语言是万万不能的。<br /><br />引号&#8212;&#8212;废除对语言的宗教信仰，建立对语言的哲学思维。<br /><br />句号&#8212;&#8212;编程就是在人脑和电脑之间寻找最佳平衡点的过程。<br /><br />冒号读罢大悦，顺手一掌拍出五记马屁：&#8220;精彩之极!可谓字字珠玑、句句联璧啊。兹决定，给诸位的奖赏是&#8212;&#8212;立时下课!&#8221;<br /><br />众人欣然领赏而去。<br /><br />插语<br /><br />[1] 有两种三层架构，一种是three-layer architecture，一种是three-tier architecture。它们经常换用，但其实是有分别的：前者仅仅在逻辑进行划分，而后者在物理上也进行了划分&#8212;&#8212;不同层次的模块运行在不同的主机上。<br /><br />[2] 不少地方译作&#8216;输送带&#8217;、&#8216;传送带&#8217;，因为duct有&#8216;输送管&#8217;、&#8216;导管&#8217;之意，于是想当然地认为这表明Perl在internet上起着输送作用。殊不知&#8216;duct type&#8217;专指一种万能的粘性极强的胶带，用以比喻Perl的粘合力。<br /><br />[3] 这类线程被称为绿色线程(green thread)，也称伪线程。据称Ruby2.0将支持原生线程(native thread)。<br /><br />[4] PHP将在5.3.0支持namespace，将在6.0支持unicode。<br /><br />总结<br /><br />&#9670; 比起Java平台和.NET平台，动态语言轻便灵活、开发效率高，但整合凝聚力还不够，在运行效率、类型安全、可用资源、开发工具、技术支持以及影响力等方面也有一定差距，故通常作为轻量级的解决方案。<br /><br />&#9670; LAMP是由Linux、Apache、MySQL和包括PHP、Perl、Python或Ruby在内的脚本语言组成的网络开发平台，具有开放灵活、开发迅速、部署方便、高可配置、安全可靠、成本低廉等优点。<br /><br />&#9670; Perl精练、复杂、强大、灵活、自由、隐晦、表现力强，但规范性、可读性、一致性、整洁性和可维护性较差。<br /><br />&#9670; Python优雅规范、简洁明晰、易学易用、类库丰富，但效率稍差，有些人不喜欢它对空白符敏感的特性。<br /><br />&#9670; Ruby语法精巧、高度灵活，兼具Perl的表现力和Python的可读性，尤其注重程序员的感受，但其性能和线程模型尚有待改进。<br /><br />&#9670; PHP简单、专一、实用、流行，在但相比其他三种语言，在语法和功能上稍有欠缺。<br /><br />&#9670; RoR是一种轻量级套餐式的web应用解决方案，是由好的设计(MVC架构和CoC、DRY原则)加上好的语言(Ruby)在好的时机(web2.0和敏捷开发风行之际)打造出的好的框架。<br /><br />&#9670; 静态语言与动态语言从语言特征到运行环境都在逐渐融合。<br /><br />&#9670; 程序员应该与程序语言一样，既要有自己的专长，又要向通用化和全能化发展。<br /><br />&#9670; 编程语言惯例用法、哲学理念和编程范式形成了语言的编程风格。</div><img src ="http://www.blogjava.net/wealupa/aggbug/381724.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wealupa/" target="_blank">常言笑</a> 2012-06-28 15:41 <a href="http://www.blogjava.net/wealupa/archive/2012/06/28/381724.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>LAMP网站架构方案分析</title><link>http://www.blogjava.net/wealupa/archive/2012/06/28/381722.html</link><dc:creator>常言笑</dc:creator><author>常言笑</author><pubDate>Thu, 28 Jun 2012 07:00:00 GMT</pubDate><guid>http://www.blogjava.net/wealupa/archive/2012/06/28/381722.html</guid><wfw:comment>http://www.blogjava.net/wealupa/comments/381722.html</wfw:comment><comments>http://www.blogjava.net/wealupa/archive/2012/06/28/381722.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wealupa/comments/commentRss/381722.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wealupa/services/trackbacks/381722.html</trackback:ping><description><![CDATA[<div>LAMP（Linux-Apache-MySQL-PHP）网站架构是目前国际流行的Web框架，该框架包括：Linux操作系统，Apache网 络服务器，MySQL数据库，Perl、PHP或者Python编程语言，所有组成产品均是开源软件，是国际上成熟的架构框架，很多流行的商业应用都是采 取这个架构，和Java/J2EE架构相比，LAMP具有Web资源丰富、轻量、快速开发等特点，微软的.NET架构相比，LAMP具有通用、跨平台、高 性能、低价格的优势，因此LAMP无论是性能、质量还是价格都是企业搭建网站的首选平台。<p>　　对于大流量、大并发量的网站系统架构来说，除 了硬件上使用高性能的服务器、负载均衡、CDN等之外，在软件架构上需要重点关注下面几个环节：使用高性能的操作系统（OS）、高性能的网页服务器 （Web Server）、高性能的数据库（Databse）、高效率的编程语言等。下面我将从这几点对其一一讨论。</p><p>　　<strong>操作系统</strong></p><p>　 　Linux操作系统有很多个不同的发行版，如Red Hat Enterprise Linux、SUSE Linux  Enterprice、Debian、Ubuntu、CentOS等，每一个发行版都有自己的特色，比如RHEL的稳定，Ubuntu的易用，基于稳定性 和性能的考虑，操作系统选择CentOS（Community ENTerprise Operating System）是一个理想的方案。</p><p>　 　CentOS（Community ENTerprise Operating System）是Linux发行版之一，是RHEL/Red Hat  Enterprise Linux的精简免费版，和RHEL为同样的源代码，不过，RHEL和SUSE  LE等企业版，提供的升级服务均是收费升级，无法免费在线升级，因此要求免费的高度稳定性的服务器可以用CentOS替代Red Hat  Enterprise Linux使用。</p><p><img alt="LAMP网站架构方案分析" src="http://www.williamlong.info/upload/1908_1.jpg" /></p><p>LAMP网站架构图</p><p>　　<strong>Web服务器、缓存和PHP加速</strong></p><p>　 　Apache是LAMP架构最核心的Web  Server，开源、稳定、模块丰富是Apache的优势。但Apache的缺点是有些臃肿，内存和CPU开销大，性能上有损耗，不如一些轻量级的Web 服务器（例如nginx）高效，轻量级的Web服务器对于静态文件的响应能力来说远高于Apache服务器。</p><p>　　Apache做为Web  Server是负载PHP的最佳选择，如果流量很大的话，可以采用nginx来负载非PHP的Web请求。nginx是一个高性能的HTTP和反向代理服 务器，Nginx以它的稳定性、丰富的功能集、示例配置文件和低系统资源的消耗而闻名。Nginx不支持PHP和CGI等动态语言，但支持负载均衡和容 错，可和Apache配合使用，是轻量级的HTTP服务器的首选。</p><p>　　Web服务器的缓存也有多种方案，Apache提供了自己的缓存模 块，也可以使用外加的Squid模块进行缓存，这两种方式均可以有效的提高Apache的访问响应能力。Squid  Cache是一个Web缓存服务器，支持高效的缓存，可以作为网页服务器的前置cache服务器缓存相关请求来提高Web服务器的速度，把Squid放在 Apache的前端来缓存Web服务器生成的动态内容，而Web应用程序只需要适当地设置页面实效时间即可。如访问量巨大则可考虑使用memcache作 为分布式缓存。</p><p>　　PHP的加速使用eAccelerator加速器，eAccelerator是一个自由开放源码PHP加速器，优化和动 态内容缓存，提高了性能PHP脚本的缓存性能，使得PHP脚本在编译的状态下，对服务器的开销几乎完全消除。它还有对脚本起优化作用，以加快其执行效率。 使PHP程序代码执效率能提高1-10倍。</p><p>　　具体的解决方案有以下几种：</p><p>　　1、squid + Apache + PHP + eAccelerator</p><p>　　使用Apache负载PHP，使用squid进行缓存，html或图片的请求可以直接由squid返回给用户。很多大型网站都采用这种架构。</p><p>　　2、nginx/Apache + PHP（fastcgi） + eAccelerator</p><p>　　使用nginx或Apache负载PHP，PHP使用fastcgi方式运行，效率较高。</p><p>　　3、nginx + Apache + PHP + eAccelerator</p><p>　　此方案综合了nginx和Apache的优点，使用Apache负载PHP，nginx负责解析其他Web请求，使用nginx的rewrite模块，Apache端口不对外开放。</p><p>　　<strong>数据库</strong></p><p>　 　开源的数据库中，MySQL在性能、稳定性和功能上是首选，可以达到百万级别的数据存储，网站初期可以将MySQL和Web服务器放在一起，但是当访问 量达到一定规模后，应该将MySQL数据库从Web Server上独立出来，在单独的服务器上运行，同时保持Web  Server和MySQL服务器的稳定连接。</p><p>　　当数据库访问量达到更大的级别，可以考虑使用MySQL Cluster等数据库集群或者库表散列等解决方案。</p><p>　　总的来说，LAMP架构的网站性能会远远优于Windows IIS + ASP + Access（例如月光博客）这样的网站，可以负载的访问量也非常大，国内的大量个人网站如果想要支撑大访问量，采用LAMP架构是一个不错的方案。</p><p>　　综上所述，基于LAMP架构设计具有成本低廉、部署灵活、快速开发、安全稳定等特点，是Web网络应用和环境的优秀组合。</p></div><img src ="http://www.blogjava.net/wealupa/aggbug/381722.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wealupa/" target="_blank">常言笑</a> 2012-06-28 15:00 <a href="http://www.blogjava.net/wealupa/archive/2012/06/28/381722.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>大型网站架构设计及技术分析</title><link>http://www.blogjava.net/wealupa/archive/2012/06/28/381720.html</link><dc:creator>常言笑</dc:creator><author>常言笑</author><pubDate>Thu, 28 Jun 2012 06:53:00 GMT</pubDate><guid>http://www.blogjava.net/wealupa/archive/2012/06/28/381720.html</guid><wfw:comment>http://www.blogjava.net/wealupa/comments/381720.html</wfw:comment><comments>http://www.blogjava.net/wealupa/archive/2012/06/28/381720.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wealupa/comments/commentRss/381720.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wealupa/services/trackbacks/381720.html</trackback:ping><description><![CDATA[<div><span style="font-size:16px;">一个小型的网站，比如个人网站，可以使用最简单的html静态页面就实现了，配合一 些图片达到美化效果，所有的页面均存放在一个目录下，这样的网站对系统架构、性能的要求都很简单，随着互联网业务的不断丰富，网站相关的技术经过这些年的 发展，已经细分到很细的方方面面，尤其对于大型网站来说，所采用的技术更是涉及面非常广，从硬件到软件、编程语言、数据库、WebServer、防火墙等 各个领域都有了很高的要求，已经不是原来简单的html静态网站所能比拟的。 </span><p style="padding-bottom: 0px; line-height: 21px; margin: 1em 0px 0.5em; padding-left: 0px; padding-right: 0px; font-size: 14px; padding-top: 0px"><span style="font-size:16px;">&nbsp;&nbsp;&nbsp; 大型网站，比如门户网站。在面对大量用户访问、高并发请求方面，基本的解决方案集中在这样几个环节：使用高性能的服务器、高性能的数据库、高效率的编程语言、还有高性能的Web容器。但是除了这几个方面，还没法根本解决大型网站面临的高负载和高并发问题。</span></p><p style="padding-bottom: 0px; line-height: 21px; margin: 1em 0px 0.5em; padding-left: 0px; padding-right: 0px; font-family: verdana, sans-serif; font-size: 14px; padding-top: 0px"><span style="font-size:16px;">&nbsp;&nbsp;&nbsp; 上面提供的几个解决思路在一定程度上也意味着更大的投入，并且这样的解决思路具备瓶颈，没有很好的扩展性，下面我从低成本、高性能和高扩张性的角度来说说我的一些经验 。</span></p><p style="padding-bottom: 0px; line-height: 21px; margin: 1em 0px 0.5em; padding-left: 0px; padding-right: 0px; font-size: 14px; padding-top: 0px"><strong><span style="font-size:16px;">1、HTML静态化</span></strong></p><p style="padding-bottom: 0px; line-height: 21px; margin: 1em 0px 0.5em; padding-left: 0px; padding-right: 0px; font-family: verdana, sans-serif; font-size: 14px; padding-top: 0px"><span style="font-size:16px;">&nbsp;&nbsp;&nbsp;   其实大家都知道，效率最高、消耗最小的就是纯静态化的html页面，所以我们尽可能使我们的网站上的页面采用静态页面来实现，这个最简单的方法其实也是最 有效的方法。但是对于大量内容并且频繁更新的网站，我们无法全部手动去挨个实现，于是出现了我们常见的信息发布系统CMS  ，像我们常访问的各个门户站点的新闻频道，甚至他们的其他频道，都是通过信息发布系统来管理和实现的，信息发布系统可以实现最简单的信息录入自动生成静态 页面，还能具备频道管理、权限管理、自动抓取等功能，对于一个大型网站来说，拥有一套高效、可管理的CMS是必不可少的。</span></p><p style="padding-bottom: 0px; line-height: 21px; margin: 1em 0px 0.5em; padding-left: 0px; padding-right: 0px; font-family: verdana, sans-serif; font-size: 14px; padding-top: 0px"><span style="font-size:16px;">&nbsp;&nbsp;&nbsp; 除了门户和信息发布类型的网站，对于交互性要求很高的社区类型网站来说，尽可能的静态化也是提高性能的必要手段，将社区内的帖子、文章进行实时的静态化，有更新的时候再重新静态化也是大量使用的策略，像Mop的大杂烩就是使用了这样的策略，网易社区等也是如此。</span></p><p style="padding-bottom: 0px; line-height: 21px; margin: 1em 0px 0.5em; padding-left: 0px; padding-right: 0px; font-family: verdana, sans-serif; font-size: 14px; padding-top: 0px"><span style="font-size:16px;">&nbsp;&nbsp;&nbsp;   同时，html静态化也是某些缓存策略使用的手段，对于系统中频繁使用数据库查询但是内容更新很小的应用，可以考虑使用html静态化来实现，比如论坛中 论坛的公用设置信息，这些信息目前的主流论坛都可以进行后台管理并且存储在数据库中，这些信息其实大量被前台程序调用，但是更新频率很小，可以考虑将这部 分内容进行后台更新的时候进行静态化，这样避免了大量的数据库访问请求。</span></p><p style="padding-bottom: 0px; line-height: 21px; margin: 1em 0px 0.5em; padding-left: 0px; padding-right: 0px; font-family: verdana, sans-serif; font-size: 14px; padding-top: 0px"><strong><span style="font-size:16px;">2、图片服务器分离</span></strong></p><p style="padding-bottom: 0px; line-height: 21px; margin: 1em 0px 0.5em; padding-left: 0px; padding-right: 0px; font-family: verdana, sans-serif; font-size: 14px; padding-top: 0px"><span style="font-size:16px;">&nbsp;&nbsp;&nbsp;   大家知道，对于Web服务器来说，不管是Apache、IIS还是其他容器，图片是最消耗资源的，于是我们有必要将图片与页面进行分离，这是基本上大型网 站都会采用的策略，他们都有独立的图片服务器，甚至很多台图片服务器。这样的架构可以降低提供页面访问请求的服务器系统压力，并且可以保证系统不会因为图 片问题而崩溃，在应用服务器和图片服务器上，可以进行不同的配置优化，比如apache在配置ContentType的时候可以尽量少支持，尽可能少的 LoadModule，保证更高的系统消耗和执行效率。</span></p><p style="padding-bottom: 0px; line-height: 21px; margin: 1em 0px 0.5em; padding-left: 0px; padding-right: 0px; font-family: verdana, sans-serif; font-size: 14px; padding-top: 0px"><strong><span style="font-size:16px;">3、数据库集群和库表散列</span></strong></p><p style="padding-bottom: 0px; line-height: 21px; margin: 1em 0px 0.5em; padding-left: 0px; padding-right: 0px; font-family: verdana, sans-serif; font-size: 14px; padding-top: 0px"><span style="font-size:16px;">&nbsp;&nbsp;&nbsp;   大型网站都有复杂的应用，这些应用必须使用数据库，那么在面对大量访问的时候，数据库的瓶颈很快就能显现出来，这时一台数据库将很快无法满足应用，于是我 们需要使用数据库集群或者库表散列。在数据库集群方面，很多数据库都有自己的解决方案，  Oracle、Sybase等都有很好的方案，常用的MySQL提供的Master/Slave也是类似的方案，您使用了什么样的DB，就参考相应的解决 方案来实施即可。</span></p><p style="padding-bottom: 0px; line-height: 21px; margin: 1em 0px 0.5em; padding-left: 0px; padding-right: 0px; font-family: verdana, sans-serif; font-size: 14px; padding-top: 0px"><span style="font-size:16px;">&nbsp;&nbsp;&nbsp;   上面提到的数据库集群由于在架构、成本、扩张性方面都会受到所采用DB类型的限制，于是我们需要从应用程序的角度来考虑改善系统架构，库表散列是常用并且 最有效的解决方案。我们在应用程序中安装业务和应用或者功能模块将数据库进行分离，不同的模块对应不同的数据库或者表，再按照一定的策略对某个页面或者功 能进行更小的数据库散列，比如用户表，按照用户ID进行表散列，这样就能够低成本的提升系统的性能并且有很好的扩展性。sohu的论坛就是采用了这样的架 构，将论坛的用户、设置、帖子等信息进行数据库分离，然后对帖子、用户按照板块和ID进行散列数据库和表，最终可以在配置文件中进行简单的配置便能让系统 随时增加一台低成本的数据库进来补充系统性能。</span></p><p style="padding-bottom: 0px; line-height: 21px; margin: 1em 0px 0.5em; padding-left: 0px; padding-right: 0px; font-family: verdana, sans-serif; font-size: 14px; padding-top: 0px"><span style="font-size:16px;"><strong>4、缓存</strong> </span></p><p style="padding-bottom: 0px; line-height: 21px; margin: 1em 0px 0.5em; padding-left: 0px; padding-right: 0px; font-size: 14px; padding-top: 0px"><span style="font-size:16px;">&nbsp;&nbsp;&nbsp;   缓存一词搞技术的都接触过，很多地方用到缓存。网站架构和网站开发中的缓存也是非常重要。这里先讲述最基本的两种缓存。高级和分布式的缓存在后面讲述。架 构方面的缓存，对Apache比较熟悉的人都能知道Apache提供了自己的缓存模块，也可以使用外加的Squid模块进行缓存，这两种方式均可以有效的 提高Apache的访问响应能力。</span></p><p style="padding-bottom: 0px; line-height: 21px; padding-left: 0px; padding-right: 0px; font-family: verdana, sans-serif; margin-bottom: 0.5em; margin-left: 0px; font-size: 14px; margin-right: 0px; padding-top: 0px"><span style="font-size:16px;">&nbsp;&nbsp;&nbsp;  网站程序开发方面的缓存，Linux上提供的Memory Cache是常用的缓存接口，可以在web开发中使  用，比如用Java开发的时候就可以调用MemoryCache对一些数据进行缓存和通讯共享，一些大型社区使用了这样的架构。另外，在使用web语言开 发的时候，各种语言基本都有自己的缓存模块和方法。</span></p><p style="padding-bottom: 0px; line-height: 21px; margin: 1em 0px 0.5em; padding-left: 0px; padding-right: 0px; font-family: verdana, sans-serif; font-size: 14px; padding-top: 0px"><strong><span style="font-size:16px;">5、镜像</span></strong></p><p style="padding-bottom: 0px; line-height: 21px; margin: 1em 0px 0.5em; padding-left: 0px; padding-right: 0px; font-family: verdana, sans-serif; font-size: 14px; padding-top: 0px"><span style="font-size:16px;">&nbsp;&nbsp;&nbsp;   镜像是大型网站常采用的提高性能和数据安全性的方式，镜像的技术可以解决不同网络接入商和地域带来的用户访问速度差异，比如ChinaNet和 EduNet之间的差异就促使了很多网站在教育网内搭建镜像站点，数据进行定时更新或者实时更新。在镜像的细节技术方面，这里不阐述太深，有很多专业的现 成的解决架构和产品可选。也有廉价的通过软件实现的思路，比如Linux上的rsync等工具 。</span></p><p style="padding-bottom: 0px; line-height: 21px; margin: 1em 0px 0.5em; padding-left: 0px; padding-right: 0px; font-size: 14px; padding-top: 0px"><strong><span style="font-size:16px;">6、负载均衡</span></strong></p><p style="padding-bottom: 0px; line-height: 21px; margin: 1em 0px 0.5em; padding-left: 0px; padding-right: 0px; font-family: verdana, sans-serif; font-size: 14px; padding-top: 0px"><span style="font-size:16px;">&nbsp;&nbsp;&nbsp; 负载均衡将是大型网站解决高负荷访问和大量并发请求采用的终极解决办法。</span></p><p style="padding-bottom: 0px; line-height: 21px; margin-top: 1em; padding-left: 0px; padding-right: 0px; font-family: verdana, sans-serif; margin-left: 0px; font-size: 14px; margin-right: 0px; padding-top: 0px"><span style="font-size:16px;">&nbsp;&nbsp;&nbsp; 负载均衡技术发展了多年，有很多专业的服务提供商和产品可以选择，我个人接触过一些解决方法，其中有两个架构可以给大家做参考。</span></p><p style="padding-bottom: 0px; line-height: 21px; margin: 1em 0px 0.5em; padding-left: 0px; padding-right: 0px; font-family: verdana, sans-serif; font-size: 14px; padding-top: 0px"><span style="font-size:16px;">硬件四层交换</span></p><p style="padding-bottom: 0px; margin: 1em 0px 0.5em; padding-left: 0px; padding-right: 0px; font-family: verdana, sans-serif; font-size: 14px; padding-top: 0px"><span style="font-size:16px;">&nbsp;&nbsp;&nbsp;   第四层交换使用第三层和第四层信息包的报头信息，根据应用区间识别业务流，将整个区间段的业务流分配到合适的应用服务器进行处理。第四层交换功能就象是虚 IP，指向物理服务器。它传输的业务服从的协议多种多样，有HTTP、FTP、NFS、Telnet或其他协议。这些业务在物理服务器基础上，需要复杂的 载量平衡算法。在IP世界，业务类型由终端TCP或UDP  端口地址来决定，在第四层交换中的应用区间则由源端和终端IP地址、TCP和UDP端口共同决定。</span></p><p style="padding-bottom: 0px; line-height: 21px; margin: 1em 0px 0.5em; padding-left: 0px; padding-right: 0px; font-family: verdana, sans-serif; font-size: 14px"><span style="font-size:16px;">&nbsp;&nbsp;&nbsp; 在硬件四层交换产品领域，有一些知名的产品可以选择，比如Alteon、F5等，这些产品很昂贵，但是物有所值，能够提供非常优秀的性能和很灵活的管理能力。Yahoo中国当初接近2000台服务器使用了三四台Alteon就搞定了。</span></p><p style="padding-bottom: 0px; line-height: 21px; margin: 1em 0px 0.5em; padding-left: 0px; padding-right: 0px; font-family: verdana, sans-serif; font-size: 14px; padding-top: 0px"><span style="font-size:16px;">软件四层交换</span></p><p style="padding-bottom: 0px; line-height: 21px; margin: 1em 0px 0.5em; padding-left: 0px; padding-right: 0px; font-family: verdana, sans-serif; font-size: 14px; padding-top: 0px"><span style="font-size:16px;">&nbsp;&nbsp;&nbsp; 大家知道了硬件四层交换机的原理后，基于OSI模型来实现的软件四层交换也就应运而生，这样的解决方案实现的原理一致，不过性能稍差。但是满足一定量的压力还是游刃有余的，有人说软件实现方式其实更灵活，处理能力完全看你配置的熟悉能力。</span></p><p style="padding-bottom: 0px; line-height: 21px; margin: 1em 0px 0.5em; padding-left: 0px; padding-right: 0px; font-family: verdana, sans-serif; font-size: 14px; padding-top: 0px"><span style="font-size:16px;">&nbsp;&nbsp;&nbsp;  软件四层交换我们可以使用Linux上常用的LVS来解决，LVS就是Linux Virtual  Server，他提供了基于心跳线heartbeat的实时灾难应对解决方案，提高系统的鲁棒性，同时可供了灵活的虚拟VIP配置和管理功能，可以同时满 足多种应用需求，这对于分布式的系统来说必不可少。</span></p><p style="padding-bottom: 0px; line-height: 21px; margin: 1em 0px 0.5em; padding-left: 0px; padding-right: 0px; font-family: verdana, sans-serif; font-size: 14px; padding-top: 0px"><span style="font-size:16px;">&nbsp;&nbsp;&nbsp;   一个典型的使用负载均衡的策略就是，在软件或者硬件四层交换的基础上搭建squid集群，这种思路在很多大型网站包括搜索引擎上被采用，这样的架构低成 本、高性能还有很强的扩张性，随时往架构里面增减节点都非常容易。这样的架构我准备空了专门详细整理一下和大家探讨。</span></p><p style="padding-bottom: 0px; line-height: 21px; margin: 1em 0px 0.5em; padding-left: 0px; padding-right: 0px; font-family: verdana, sans-serif; font-size: 14px; padding-top: 0px"><span style="font-size:16px;">&nbsp;&nbsp;&nbsp; 对于大型网站来说，前面提到的每个方法可能都会被同时使用到，我这里介绍得比较浅显，具体实现过程中很多细节还需要大家慢慢熟悉和体会，有时一个很小的squid参数或者apache参数设置，对于系统性能的影响就会很大，希望大家一起讨论，达到抛砖引玉之效。</span></p><p style="padding-bottom: 0px; line-height: 21px; margin: 1em 0px 0.5em; padding-left: 0px; padding-right: 0px; font-family: verdana, sans-serif; font-size: 14px; padding-top: 0px"><span style="font-size:16px;">讨论大型高并发负载网站的系统架构问题，作者提出了几点建议：</span></p><p style="padding-bottom: 0px; line-height: 21px; margin: 1em 0px 0.5em; padding-left: 0px; padding-right: 0px; font-family: verdana, sans-serif; font-size: 14px; padding-top: 0px"><span style="font-size:16px;">1. HTML静态化，这可以通过CMS 自动实现；</span></p><p style="padding-bottom: 0px; line-height: 21px; margin: 1em 0px 0.5em; padding-left: 0px; padding-right: 0px; font-family: verdana, sans-serif; font-size: 14px; padding-top: 0px"><span style="font-size:16px;">2. 图片服务器分离（类似的，在视频网站中，视频文件也应独立出来）；</span></p><p style="padding-bottom: 0px; line-height: 21px; margin: 1em 0px 0.5em; padding-left: 0px; padding-right: 0px; font-family: verdana, sans-serif; padding-top: 0px"><span style="font-size:16px;">3. 数据库集群和库表散列，Oracle、MySQL等DBMS都有完美的支持；</span></p><p style="padding-bottom: 0px; line-height: 21px; margin: 1em 0px 0.5em; padding-right: 0px; font-family: verdana, sans-serif; font-size: 14px; padding-top: 0px"><span style="font-size:16px;">4. 缓存，比如使用 Apache的Squid模块，或者是开发语言的缓存模块，；</span></p><p style="padding-bottom: 0px; line-height: 21px; margin: 1em 0px 0.5em; padding-left: 0px; padding-right: 0px; font-family: verdana, sans-serif; font-size: 14px; padding-top: 0px"><span style="font-size:16px;">5. 网站镜像；</span></p><p style="padding-bottom: 0px; margin: 1em 0px 0.5em; padding-left: 0px; padding-right: 0px; font-family: verdana, sans-serif; font-size: 14px; padding-top: 0px"><span style="font-size:16px;">6. 负载均衡。</span></p><p style="padding-bottom: 0px; line-height: 21px; margin: 1em 0px 0.5em; padding-left: 0px; padding-right: 0px; font-family: verdana, sans-serif; font-size: 14px; padding-top: 0px"><span style="font-size:16px;">&nbsp;&nbsp;&nbsp;   作者将负载均衡称为&#8220;是大型网站解决高负荷访问和大量并发请求采用的终极解决办法&#8221;，并提出&#8220;一个典型的使用负载均衡的策略就是，在软件或者硬件四层交换 的基础上搭建squid集群&#8221;。在实践时可以考虑建立应用服务器集群和Web服务器集群，应用服务器集群可以采用Apache+Tomcat集群和 WebLogic集群等，Web服务器集群可以用反向代理，也可以用NAT的方式，或者多域名解析均可。</span></p><p style="padding-bottom: 0px; line-height: 21px; margin: 1em 0px 0.5em; padding-left: 0px; padding-right: 0px; font-family: verdana, sans-serif; font-size: 14px; padding-top: 0px"><span style="font-size:16px;">&nbsp;&nbsp;&nbsp;  从提升网站性能的角度出发，静态资源不应和应用服务器放在一起，数据库服务器也应尽  量独立开来。在典型的MVC模式中，由谁来完成数据逻辑处理的，对系统性能有着至关重要的影响。以Java  EE为例，在OO的设计思想中，我们强调系统的抽象、重用、可维护性，强调下层的更改不会扩散到上层逻辑，强调系统移植的便捷性，  因而往往存在一种过分抽象的问题，比如在Hibernate的基础上再加入一层DAO的设计。另外一方面，却会忽视利用DBMS本身的优秀特性（存储过 程、触发器）来完成高效的数据处理。诚然，如果客户要求将数据从Oracle移植到MySQL，那么DBMS特性的东西越少，移植便越容易。但事实上，在 实践中，提出类似移植要求的情况非常少见，因此在做架构设计时，不一定为了这种潜在的需求而大幅牺牲系统的性能与稳定性。此外，我不建议采用分布式数据库 管理结构，这样带来的开销太大，数据维护也是个头痛的问题，尽可能采用集中式的数据管理。</span></p><p style="padding-bottom: 0px; line-height: 21px; margin: 1em 0px 0.5em; padding-left: 0px; padding-right: 0px; font-family: verdana, sans-serif; font-size: 14px; padding-top: 0px"><span style="font-size:16px;">&nbsp;&nbsp;&nbsp;   在商业系统中，算法逻辑本身并不复杂，在这种情况下，程序设计本身的好坏不会对系统的性能造成致命的影响。重要的影响因素反而变为软件系统架构本身。在传 统的CORBA、J2EE、DCOM等对象模  型中，我们看到专家们对分布式对象计算的理论偏好，但实践证明，对象的分布带来的恶劣影响远远胜过其积极意义。这也  是现在轻量级的开发框架受推崇的一个重要原因。如果能用简单的，就不要用复杂的，例如能够用Python、RoR完成的任务，是否一定要用Java来做？ 我看未必。对于用户来说，他们关心的不是采用什么先进的技术，而是我们提供的产品能否满足他的需求。而且，Python、RoR这些开发工具已经强大到足 以应对大部分网站应用，在各种缓存系统的帮助下，在其他技术的协调配合下，完全能够胜任高负载高并发的网站访问任务。</span></p><p style="padding-bottom: 0px; line-height: 21px; margin: 1em 0px 0.5em; padding-left: 0px; padding-right: 0px; font-family: verdana, sans-serif; font-size: 14px; padding-top: 0px"><span style="font-size:16px;">&nbsp;&nbsp;&nbsp; 在HTML静态化方面，如果是对于更新相对较少的页面，可以这样处理，例如新闻、社区通告、或者类似与淘宝网的产品分类信息。但若数据更新频繁，这样做的意义便不大。</span></p><p style="padding-bottom: 0px; line-height: 21px; margin: 1em 0px 0.5em; padding-left: 0px; padding-right: 0px; font-family: verdana, sans-serif; font-size: 14px; padding-top: 0px"><span style="font-size:16px;">&nbsp;&nbsp;&nbsp; 网站镜像是个传统的技术，更高级的应用来自流媒体领域的CDN(Content Delivery Network)，CDN的概念可以由流媒体数据扩展到图片、视频文件等静态资源的传输。不过，在电子商务领域，很少有这样的应用。</span></p><p style="padding-bottom: 0px; line-height: 21px; margin: 1em 0px 0.5em; padding-left: 0px; padding-right: 0px; font-family: verdana, sans-serif; font-size: 14px; padding-top: 0px">&nbsp;</p><p style="padding-bottom: 0px; line-height: 21px; margin: 1em 0px 0.5em; padding-left: 0px; padding-right: 0px; font-family: verdana, sans-serif; font-size: 14px; padding-top: 0px"><span style="font-size:16px;">开源平台的高并发集群思考目前碰到的高并发应用，需要高性能需求的主要是两个方面:</span></p><p style="padding-bottom: 0px; line-height: 21px; margin: 1em 0px 0.5em; padding-left: 0px; padding-right: 0px; font-family: verdana, sans-serif; font-size: 14px; padding-top: 0px"><span style="font-size:16px;">1。网络</span></p><p style="padding-bottom: 0px; line-height: 21px; margin: 1em 0px 0.5em; padding-left: 0px; padding-right: 0px; font-family: verdana, sans-serif; font-size: 14px; padding-top: 0px"><span style="font-size:16px;">2。数据库 </span></p><p style="padding-bottom: 0px; line-height: 21px; margin: 1em 0px 0.5em; padding-left: 0px; padding-right: 0px; font-size: 14px; padding-top: 0px"><span style="font-size:16px;">这两个方面的解决方式其实还是一致的</span></p><p style="padding-bottom: 0px; line-height: 21px; margin: 1em 0px 0.5em; padding-left: 0px; padding-right: 0px; font-family: verdana, sans-serif; font-size: 14px; padding-top: 0px"><span style="font-size:16px;">1。充分接近单机的性能瓶颈，自我优化</span></p><p style="padding-bottom: 0px; line-height: 21px; margin: 1em 0px 0.5em; padding-left: 0px; padding-right: 0px; font-family: verdana, sans-serif; font-size: 14px; padding-top: 0px"><span style="font-size:16px;">2。单机搞不定的时候(数据传输瓶颈:单位时间内磁盘读写/网络数据包的收发cpu计算瓶颈)，把负荷分担给多台机器，就是所谓的负载均衡</span></p><p style="padding-bottom: 0px; line-height: 21px; margin: 1em 0px 0.5em; padding-left: 0px; padding-right: 0px; font-family: verdana, sans-serif; font-size: 14px; padding-top: 0px"><span style="font-size:16px;">网络方面单机的处理</span></p><p style="padding-bottom: 0px; line-height: 21px; margin: 1em 0px 0.5em; padding-left: 0px; padding-right: 0px; font-family: verdana, sans-serif; font-size: 14px; padding-top: 0px"><span style="font-size:16px;">1。底层包收发处理的模式变化(从select 模式到epoll / kevent)</span></p><p style="padding-bottom: 0px; line-height: 21px; margin: 1em 0px 0.5em; padding-left: 0px; padding-right: 0px; font-family: verdana, sans-serif; font-size: 14px; padding-top: 0px"><span style="font-size:16px;">2。应用模式的变化</span></p><p style="padding-bottom: 0px; line-height: 21px; margin: 1em 0px 0.5em; padding-left: 0px; padding-right: 0px; font-family: verdana, sans-serif; font-size: 14px; padding-top: 0px"><span style="font-size:16px;">2.1 应用层包的构造方式</span></p><p style="padding-bottom: 0px; line-height: 21px; margin: 1em 0px 0.5em; padding-left: 0px; padding-right: 0px; font-family: verdana, sans-serif; font-size: 14px; padding-top: 0px"><span style="font-size:16px;">2.2 应用协议的实现</span></p><p style="padding-bottom: 0px; line-height: 21px; margin: 1em 0px 0.5em; padding-left: 0px; padding-right: 0px; font-family: verdana, sans-serif; font-size: 14px; padding-top: 0px"><span style="font-size:16px;">2.3 包的缓冲模式</span></p><p style="padding-bottom: 0px; line-height: 21px; padding-left: 0px; padding-right: 0px; font-family: verdana, sans-serif; margin-bottom: 0.5em; margin-left: 0px; font-size: 14px; margin-right: 0px; padding-top: 0px"><span style="font-size:16px;">2.4 单线程到多线程</span></p><p style="padding-bottom: 0px; line-height: 21px; margin: 1em 0px 0.5em; padding-left: 0px; padding-right: 0px; font-family: verdana, sans-serif; font-size: 14px; padding-top: 0px"><span style="font-size:16px;">网络负载均衡的几个办法</span></p><p style="padding-bottom: 0px; line-height: 21px; margin: 1em 0px 0.5em; padding-left: 0px; padding-right: 0px; font-family: verdana, sans-serif; font-size: 14px; padding-top: 0px"><span style="font-size:16px;">1。代理模式：代理服务器只管收发包，收到包以后转给后面的应用服务器群（服务器群后可能还会有一堆堆的数据库服务器等等），并且把返回的结果再返回给请求端</span></p><p style="padding-bottom: 0px; margin: 1em 0px 0.5em; padding-left: 0px; padding-right: 0px; font-family: verdana, sans-serif; font-size: 14px; padding-top: 0px"><span style="font-size:16px;">2。虚拟代理ip：代理服务器收发包还负载太高，那就增加多台代理服务器，都来管包的转发。这些代理服务器可以用统一的虚拟ip，也可以单独的ip</span></p><p style="padding-bottom: 0px; line-height: 21px; margin: 1em 0px 0.5em; padding-left: 0px; padding-right: 0px; font-family: verdana, sans-serif; font-size: 14px; padding-top: 0px"><span style="font-size:16px;">3。p2p：一些广播的数据可以p2p的模式来减轻服务器的网络压力</span></p><p style="padding-bottom: 0px; line-height: 21px; margin: 1em 0px 0.5em; padding-right: 0px; font-family: verdana, sans-serif; font-size: 14px; padding-top: 0px"><span style="font-size:16px;">数据库(指mysql)单 机的处理</span></p><p style="padding-bottom: 0px; line-height: 21px; margin: 1em 0px 0.5em; padding-left: 0px; padding-right: 0px; font-family: verdana, sans-serif; font-size: 14px; padding-top: 0px"><span style="font-size:16px;">1。数据库本身结构的设计优化（分表，分记录，目的在于保证每个表的记录数在可定的范围内）</span></p><p style="padding-bottom: 0px; line-height: 21px; margin: 1em 0px 0.5em; padding-left: 0px; padding-right: 0px; font-family: verdana, sans-serif; font-size: 14px; padding-top: 0px"><span style="font-size:16px;">2。sql语句的优化</span></p><p style="padding-bottom: 0px; line-height: 21px; padding-left: 0px; padding-right: 0px; font-family: verdana, sans-serif; margin-bottom: 0.5em; margin-left: 0px; font-size: 14px; margin-right: 0px; padding-top: 0px"><span style="font-size:16px;">3。master + slave模式</span></p><p style="padding-bottom: 0px; line-height: 21px; margin: 1em 0px 0.5em; padding-left: 0px; padding-right: 0px; font-family: verdana, sans-serif; font-size: 14px; padding-top: 0px"><span style="font-size:16px;">数据库集群的处理</span></p><p style="padding-bottom: 0px; line-height: 21px; padding-left: 0px; padding-right: 0px; font-family: verdana, sans-serif; margin-bottom: 0.5em; margin-left: 0px; font-size: 14px; margin-right: 0px; padding-top: 0px"><span style="font-size:16px;">1。master + slave模式 （可有效地处理 并发查询）</span></p><p style="padding-bottom: 0px; line-height: 21px; margin: 1em 0px 0.5em; padding-left: 0px; padding-right: 0px; font-family: verdana, sans-serif; font-size: 14px; padding-top: 0px"><span style="font-size:16px;">2。mysql cluster 模式 （可有效地处理并发数据变化）</span></p></div><img src ="http://www.blogjava.net/wealupa/aggbug/381720.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wealupa/" target="_blank">常言笑</a> 2012-06-28 14:53 <a href="http://www.blogjava.net/wealupa/archive/2012/06/28/381720.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>大型互联网网站架构心得</title><link>http://www.blogjava.net/wealupa/archive/2012/06/28/381719.html</link><dc:creator>常言笑</dc:creator><author>常言笑</author><pubDate>Thu, 28 Jun 2012 06:48:00 GMT</pubDate><guid>http://www.blogjava.net/wealupa/archive/2012/06/28/381719.html</guid><wfw:comment>http://www.blogjava.net/wealupa/comments/381719.html</wfw:comment><comments>http://www.blogjava.net/wealupa/archive/2012/06/28/381719.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/wealupa/comments/commentRss/381719.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wealupa/services/trackbacks/381719.html</trackback:ping><description><![CDATA[<div>     <p>我们知道，对于一个大型网站来说，可伸缩性是非常重要的，怎么样在纵向和横向有良好的可伸缩性，就需要在做架构设计的时候考虑到一个分的原则，我想在多个方面说一下怎么分：</p><p> &nbsp; &nbsp;首先是横向的分：</p><p> &nbsp; &nbsp;1. 大的网站化解为多个小网站：当我们一个网站有多个功能的时候，可以考虑把这个网站拆分成几个小模块，每一个模块可以是一个网站，这样的话我们到时候就可以很灵活地去把这些网站部署到不同的服务器上。</p><p>  &nbsp; &nbsp;2.  静态动态分离：静态文件和动态文件最好分离开成2个网站，我们知道静态网站和动态网站对服务器来说压力的侧重不同，前者可能重IO后者重CPU，那么我们 在选择硬件的时候也可以有侧重，而且静态和动态内容的缓存策略也不一样。典型的应用，我们一般会有独立的文件或图片服务器。而且，使用不用的域名还可以提 高浏览器并行加载的能力。</p><p> &nbsp; &nbsp;3. 按照功能来分：比如有一个模块是负责上传的，上传操作很消耗时间，如果和其它应用混在一起的话很可能，一点点访问就会使服务器瘫痪，这种特殊的模块应该分开。安全的不安全的也要分开，还需要考虑到以后SSL的购买。</p><p> &nbsp; &nbsp;4. 我们不一定要全部用自己的服务器，搜索、报表可以依靠别人的服务，比如google的搜索和报表服务，自己做的不一定比得过别人，服务器带宽都省了。</p><p> &nbsp; &nbsp;其次是纵向的分：</p><p> &nbsp; &nbsp;1. 文件也相当于数据库，IO的流量可能比数据库还大，这也算是纵向级别的访问，上传的文件图片一定要和WEB服务器分开。当然，数据库和网站都放在一个服务器上的很少了，这是最基本的。</p><p>  &nbsp; &nbsp;2.  对于涉及到数据库访问的动态程序来说，我们可以使用一个中间层（所谓的应用层或逻辑层）来访问数据库（部署在独立的服务器上），最大的好处就是缓存和灵活 性。缓存的内存占用比较大，我们要把它和网站进程分开，而且这样做我们可以很方便的去改变一些数据访问的策略，即使到时候数据库有分布的话在这里可以做一 个调配工作，这样灵活性就很大了。还有好处是中间层可以做电线网通桥梁，可能网通访问双线再访问电信会比网通直接访问电信服务器快。</p><p> &nbsp;  &nbsp;有人说我不分，我可以做负载均衡，对，是可以的，但是如果分的话，同样的10台机器肯定比不分10台机器可以承受更多的访问量，而且对硬件的需求可能不 会很高，因为知道需要哪个硬件特别好。争取让每一个服务期都不空闲，又都不是太忙，合理进行组合调整和扩充，这样的系统伸缩性就高了，能根据访问量来调整 的前提就是之前有考虑到分，分的好处是灵活性、伸缩性、隔离性以及安全性。</p><p> &nbsp; &nbsp;对服务器来说，我们有几点是要长期观察的，任何一点都可能是瓶颈：</p><p> &nbsp; &nbsp;1. CPU：动态文件的解析需要比较多的CPU，CPU出现瓶颈就要看是不是哪个功能过长时间占用线程，如果是就分出去。或者就是每一个请求处理时间不长，但是访问量很高，那么就加服务器。CPU是好东西，不能让他干等，不做事情。</p><p> &nbsp; &nbsp;2. 内存：缓存从IIS进程独立出去，一般对WEB服务器来说内存不够的情况不是很多。内存比磁盘快，要合理利用。</p><p> &nbsp; 3. 磁盘IO：用性能监视器找到哪些文件IO特别大，找到了就分到独立的一组文件服务器上去，或者直接做CDN。磁盘慢，大规模读取数据的应用靠缓存，大规模写入数据的应用可以靠队列来降低突发的并发。</p><p>  &nbsp; &nbsp;4.  网络：我们知道，网络的通讯是比较慢的，比磁盘还慢，如果是做分布式缓存，分布式计算的话，要考虑到物理服务器之间网络通讯的时间，当然，在流量大了以 后，这可以提高系统的接纳能力一个等级。静态内容可以借助CSD分担一部分，在做服务器假设的时候还要考虑中国特色的电信网通情况以及防火墙。</p><p> &nbsp; 对SQL SERVER数据库服务器来说：</p><p> &nbsp; &nbsp;其实还是水平分割和纵向分割，一个二维表，水平分割就是横过来切一刀，纵向分割就是竖直切一刀：</p><p> &nbsp; &nbsp;1、纵向分割就是，我们不同的应用可以分到不同的DB中，不同的实例中，或者说把某个拥有很多字段的表拆分成小表。</p><p>  &nbsp;  &nbsp;2、横向分割就是，某些应用可能不负载，比如用户注册，但是用户表会非常大，可以把大表分开。可以采用表分区，数据存储在不同文件上，然后再部署到独立 物理服务器增加IO吞吐以改善读写性能，土一点的做法就是自己定期把老的数据存档。表分区的另外一个优势可以增加数据查询速度，因为我们的页索引可以有多 层了，就像一个文件夹中的文件不要太多，多分几层文件夹一样。</p><p> &nbsp; &nbsp;3、还可以通过数据库镜像、复制订阅、事物日志，把读写分开到不同的镜像物理数据库上，一般来说够用，如果还不行可以用硬件来实现数据库的负载均衡。当然，对于BI，我们可能还会有数据仓库。</p><p> &nbsp; &nbsp; &nbsp;架构上考虑到了这些之后，流量大了，就可以在这个的基础上再去调整或者做WEB服务器或者应用服务器的负载均衡。很多时候我们都是在重复发现问题-》找到瓶颈-》解决这个过程。</p><p> &nbsp; &nbsp;典型的架构如下：</p><p id="div4556062" style="text-align:center;"><img src="http://img.ddvip.com/2012/0619/201206190553134255.jpg" height="451" width="546"  alt="" /></p><p> &nbsp; &nbsp;动态WEB服务器配好点的CPU，静态WEB服务器和文件服务器磁盘好点<br style="font-size:12px;" /> &nbsp; &nbsp;应用服务器内存大点，缓存服务器也是，数据库服务器当然内存和CPU都要好</p><p>上次说的&#8220;分&#8221;是一个比较大的原则也是一个比较高层的原则，这次我想说一下其它两个原则：并与换。</p><p> 并</p><p> &nbsp; &nbsp; 为什么要分？是因为我们希望通过分来提高系统的承载能力，那并又是并什么呢？我想了一下有几个方面可以并：</p><p> &nbsp; &nbsp; 1. 合并用户请求，最基本的就是合并CSS/图片/脚本，还可以合并页面。不过合并就可能产生流量的浪费，需要有一个平衡点。</p><p> &nbsp; &nbsp;2. 合并接口的粒度，如果做分布式应用的话，我们可能不会直接访问数据库而是调用应用层提供的接口，由于是网络调用，代价比较大，因此在设计的时候尽量提供粒度比较粗的接口，一次调用返回比较多的数据，而不是细化到添加删除修改的层次。</p><p> &nbsp; &nbsp;3. 合并接口的部署，对于频繁的跨机器调用可以考虑有一些数据冗余，把跨网络的服务编程进程间通讯，甚至转到客户端来做。比如论坛发贴时候脏词的过滤，直接调用应用层提供的接口（跨机器）是可以的，但是可能代价比较大，可以把这个接口使用IPC方式部署在本机。</p><p> 换</p><p> &nbsp; &nbsp; 时间换空间，空间换时间是常见的做法，具体一点说：</p><p>  &nbsp; &nbsp; 1.  缓存。缓存的重要性早计算机的硬件中就有重要的体现。对于网站，有很多种缓存，可以是客户端资源的缓存，可以是页面输出缓存，也可以是应用层的数据缓存， 目的都是一样的，或是减少了服务器请求次数，或是减少了请求的处理过程，或是减少了数据库的访问次数。当然，生成静态文件也可以算是一种缓存。不访问磁盘 固然不可能，但是我们要极大限度降低磁盘访问的机会。</p><p> &nbsp; &nbsp;2.  有的时候为了获取极快的响应，我们还会不惜代价采用重复计算。比如，我们的某个操作很可能会由于网络问题等原因响应比较慢，在设计的时候可以有一个统一的 处理接口，由这个接口分发到不同的服务器去异步实现这个操作，哪个服务器先返回了结果我们就用这个结果，然后杀死其他服务器的冗余操作。</p><p> &nbsp; &nbsp;3. 网站一般追求比较快的响应，一般不太会在比较高的层次用时间来换取空间，但是在一些用户独有数据的处理算法上可能还是会考虑到空间的节省问题。</p><p> &nbsp; &nbsp;4. 有的时候我们会用一些聚合表来存放聚合数据，也就是进行一些预计算提高复杂计算（比如报表）的性能。当然，对于数据分析，构建多维数据库也是一种不错的选择。</p><p>  &nbsp; &nbsp;  有很多网友留言说说的比较粗，没有什么具体的东西。我觉得架构这个东西很难去说具体怎么做，因为具体实施的时候要看情况去应用的，由于没有完美的东西，所 以做架构通常是去做一个平衡，很可能某一个侧重不同会影响到架构的实施。希望我的这些文章能给大家一个提示的作用，看了之后如果你觉得&#8220;这点我倒没有考虑 到，以后要注意&#8221;那或许就是最大的帮助了，下面我想说一些其它方面的问题，每一条都很零散，算是一个补充吧：</p><p> &nbsp; &nbsp; 1.  到底是采用已有的东西还是自己去做需要详细考虑的，采用别人的东西可能比较稳定，但是自己的控制少了一点，采用自己做的东西可以很灵活，但是可能会问题比 较多。不管怎么样，我们在采用一个第三方框架的时候务必要进行缜密的调查，看到他的不足，否则项目很可能在后期被这个框架制约，反之，决定自己去做一个框 架的时候也要看到自己需要什么其他框架不能提供的东西。</p><p> &nbsp; &nbsp;2. 数据传输的时候可以做压缩，但要考虑到压缩解压缩需要CPU资源，在IO（磁盘，带宽，传输能力）和CPU之间有一个平衡的考虑。</p><p> &nbsp; &nbsp;3. 理想的可伸缩性架构是可以自由增加或替换服务器，无需去停机维护或做很大的调整。在使用一个统一的调度中心来调度这些服务器，分配请求的时候，我们要考虑一下调度服务器能承受多少流量。</p><p> &nbsp; 4. 使用大量的廉价服务器还是少量的高配服务器？如何根据需求来组合服务器发挥最大作用。</p><p> &nbsp; &nbsp;5. 对于分布式构架，我们尽量让每一个节点保持简单的逻辑，尽量减少同一层次节点之间的依赖，另外。需要有统一的地方来管理所有的节点。</p><p> &nbsp; &nbsp;6. 功能分解、使用异步进行整合、故障转移、失效保护。</p><p> &nbsp; 7. 软件的架构升级和计算机硬件的架构升级很像，可能有一段时期，我们是在慢慢提高整体能力，2年也才提高了几倍，之后发现只有通过某种彻底的架构改变才能提高数十倍的能力，升级之后，我们或许又会遇到其他问题。就像CPU，是简单提高主频还是彻底更换架构。</p><p> &nbsp; &nbsp;8. 数据方面，读写分离、数据库分隔、功能划分、缓存、镜像。</p><p> &nbsp; 9. 硬件网络上的架构很重要，但软件开发中的一些细节不可忽略，好的架构不意味着不需要代码审阅。</p></div><img src ="http://www.blogjava.net/wealupa/aggbug/381719.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wealupa/" target="_blank">常言笑</a> 2012-06-28 14:48 <a href="http://www.blogjava.net/wealupa/archive/2012/06/28/381719.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>大型网站架构设计及技术总结</title><link>http://www.blogjava.net/wealupa/archive/2012/06/28/381717.html</link><dc:creator>常言笑</dc:creator><author>常言笑</author><pubDate>Thu, 28 Jun 2012 06:37:00 GMT</pubDate><guid>http://www.blogjava.net/wealupa/archive/2012/06/28/381717.html</guid><wfw:comment>http://www.blogjava.net/wealupa/comments/381717.html</wfw:comment><comments>http://www.blogjava.net/wealupa/archive/2012/06/28/381717.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wealupa/comments/commentRss/381717.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wealupa/services/trackbacks/381717.html</trackback:ping><description><![CDATA[<div>随着中国大型IT企业信息化速度的加快，大部分应用的数据量和访问量都急剧增加，大型企业网站正面临性能和高数据访问量的压力，而且对存储、安全以及信息检索等等方面都提出了更高的要求&#8230;&#8230;  <br />&nbsp;&nbsp;&nbsp;&nbsp; 本文中，我想通过几个国外大型IT企业及网站的成功案例，从Web技术人员角度探讨如何积极地应对国内大型网站即将面临的扩展（主要是技术方面，而较少涉及管理及营销等方面）矛盾。  <br /><br /><strong>一、 国外大型IT网站的成功之道</strong> <br />(一) MySpace <br />&nbsp;&nbsp;&nbsp;&nbsp; 今天，MySpace已经成为全球众口皆碑的社区网站之王。尽管一流和营销和管理经验自然是每个IT企业取得成功的首要因素，但是本节中我们却抛弃这一点，而主要着眼于探讨在数次面临系统扩张的紧急关头MySpace是如何从技术方面采取应对策略的。  <br />第一代架构&#8212;添置更多的Web服务器  <br />&nbsp;&nbsp;&nbsp;&nbsp;  MySpace最初的系统很小，只有两台Web服务器（分担处理用户请求的工作量）和一个数据库服务器（所有数据都存储在这一个地方）。那时使用的是   Dell双CPU、4G内存的系统。在早期阶段，MySpace基本是通过添置更多Web服务器来对付用户暴增问题的。但到在2004年早期，在   MySpace用户数增长到五十万后，其数据库服务器已经开始疲于奔命了。 <br /><br />第二代架构&#8212;增加数据库服务器  <br />&nbsp;&nbsp;&nbsp;&nbsp; 与增加Web服务器不同，增加数据库并没那么简单。如果一个站点由多个数据库支持，设计者必须考虑的是，如何在保证数据一致性的前提下让多个数据库分担压力。<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;  MySpace运行在三个SQL   Server数据库服务器上&#8212;一个为主，所有的新数据都向它提交，然后由它复制到其它两个；另两个数据库服务器全力向用户供给数据，用以在博客和个人资料 栏显示。这种方式在一段时间内效果很好&#8212;&#8212;只要增加数据库服务器，加大硬盘，就可以应对用户数和访问量的增加。<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;  这一次的数据库架构按照垂直分割模式设计，不同的数据库服务于站点的不同功能，如登录、用户资料和博客。垂直分割策略利于多个数据库分担访问压力，当用户 要求增加新功能时，MySpace只需要投入新的数据库加以支持。在账户到达二百万后，MySpace还从存储设备与数据库服务器直接交互的方式切换到    SAN（存储区域网络）&#8212;用高带宽、专门设计的网络将大量磁盘存储设备连接在一起，而数据库连接到SAN。这项措施极大提升了系统性能、正常运行时间和可 靠性。然而，当用户继续增加到三百万后，垂直分割策略也变得难以维持下去。<br /><br />第三代架构&#8212;转到分布式计算架构  <br />&nbsp;&nbsp;&nbsp;&nbsp;  几经折腾，最终，MySpace将目光移到分布式计算架构&#8212;&#8212;它在物理上分布的众多服务器，整体必须逻辑上等同于单台机器。拿数据库来说，就不能再像过去 那样将应用拆分，再以不同数据库分别支持，而必须将整个站点看作一个应用。现在，数据库模型里只有一个用户表，支持博客、个人资料和其他核心功能的数据都 存储在相同数据库。<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;  既然所有的核心数据逻辑上都组织到一个数据库，那么MySpace必须找到新的办法以分担负荷&#8212;&#8212;显然，运行在普通硬件上的单个数据库服务器是无能为力 的。这次，不再按站点功能和应用分割数据库，MySpace开始将它的用户按每百万一组分割，然后将各组的全部数据分别存入独立的SQL   Server实例。目前，MySpace的每台数据库服务器实际运行两个SQL   Server实例，也就是说每台服务器服务大约二百万用户。据MySpace的技术人员说，以后还可以按照这种模式以更小粒度划分架构，从而优化负荷分 担。  <br /><br />第四代架构&#8212;求助于微软方案  <br />&nbsp;&nbsp;&nbsp;&nbsp; 2005年早期，账户达到九百万，MySpace开始用微软的C#编写ASP.NET程序。在收到一定成效后，MySpace开始大规模迁移到ASP.NET。  <br />&nbsp;&nbsp;&nbsp;&nbsp; 账户达到一千万时，MySpace再次遭遇存储瓶颈问题。SAN的引入解决了早期一些性能问题，但站点目前的要求已经开始周期性超越SAN的I/O容量&#8212;&#8212;即它从磁盘存储系统读写数据的极限速度。  <br /><br />第五代架构&#8212;增加数据缓存层并转到支持64位处理器的SQL Server 2005  <br />&nbsp;&nbsp;&nbsp;&nbsp;   2005年春天，MySpace账户达到一千七百万，MySpace又启用了新的策略以减轻存储系统压力，即增加数据缓存层&#8212;&#8212;位于Web服务器和数据库 服务器之间，其唯一职能是在内存中建立被频繁请求数据对象的副本，如此一来，不访问数据库也可以向Web应用供给数据。<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;  2005年中期，服务账户数达到两千六百万时，MySpace因为我们对内存的渴求而切换到了还处于beta测试的支持64位处理器的SQL   Server 2005。升级到SQL Server 2005和64位Windows Server   2003后，MySpace每台服务器配备了32G内存，后于2006年再次将配置标准提升到64G。<br /><br />&nbsp;&nbsp;&nbsp;&nbsp; 事实上，MySpace的Web服务器和数据库仍然经常发生超负荷，其用户频繁遭遇&#8220;意外错误&#8221;和&#8220;站点离线维护&#8221;等告示，他们不得不在论坛抱怨不停&#8230;&#8230;  <br />&nbsp;&nbsp;&nbsp;&nbsp;   MySpace正是在这样不断重构站点软件、数据库和存储系统中，才一步步走到今天。事实上，MySpace已经成功解决了很多系统扩展性问题，其中存在 相当的经验值得我们借鉴。MySpace系统架构到目前为止保持了相对稳定，但其技术人员仍然在为SQL   Server支持的同时连接数等方面继续攻坚，尽可能把事情做到最好。 <br /><br />(二) Amazon <br />&nbsp;&nbsp;&nbsp;&nbsp; 亚马逊书店无疑是电子商务发展的里程碑。2000年到现在，世界网络业腥风血雨。Amazon曾经成为网络泡沫的头号代表。如今，当这个&#8220;最大的泡沫&#8221;用几经易改的数字把自己变成了坚实的IT巨人。  <br />&nbsp;&nbsp;&nbsp;&nbsp;   历览Amazon发展过程，其成功经验在于，它创造性地进行了电子商务中每一环节的探索，包括系统平台的建设，程序编写、网站设立、配送系统等等方面。用   Amazon当家人贝索斯的话说就是，&#8220;在现实世界的商店最有力的武器就是地段，地段，地段，而对于我们来说最重要的三件事就是技术，技术，技术。&#8221;   <br /><br />(三) eBay  <br />&nbsp;&nbsp;&nbsp;&nbsp; eBay是世界闻名的拍卖网站，eBay公司通信部主管凯文?帕斯格拉夫认为，&#8220;eBay成功的最重要原因在于公司管理和服务。&#8221;  <br />&nbsp;&nbsp;&nbsp;&nbsp; 其成功的奥秘可以列举为以下几点： <br />&nbsp;&nbsp;&nbsp;&nbsp; &#9312;敢为天下先&#8212;在网络尚不普及的时代，eBay率先进入网络拍卖领域；  <br />&nbsp;&nbsp;&nbsp;&nbsp;   &#9313;依托虚拟商场所产生的特有的&#8220;零库存&#8221;是eBay公司取得成功的另一个重要原因。该公司的核心业务没有任何库存风险，所有的商品都是由客户提供，它只需 要负责提供虚拟的拍卖平台&#8212;网络和软件。所以，eBay公司的财务报表上不会出现&#8220;库存费用&#8221;和&#8220;保管费用&#8221;等。  <br />&#9314;自eBay公司成立开始，它就一直遵循两条&#8220;黄金原则&#8221;：建设虚拟社区，给网民以家的感觉；保证网站稳定安全地运行。<br /><strong>二、  国内大型网站开发时的几点建议</strong>  <br />&nbsp;&nbsp;&nbsp;&nbsp; 从本节开始，我们将结合国内外大型IT网站在技术扩展方面的沉痛教训和成功经验，探讨在如今刚刚开始的Web  2.0时代如何应对国内网站即将面临的数据访问量增加（甚至是急剧膨胀）的问题，并提出一些供参考的策略和建议。 <br /><br />(四) 搭建科学的系统架构  <br />&nbsp;&nbsp;&nbsp;&nbsp;   构建大型的商业网站绝对不可能像构建普通的小型网站一样一蹴而就，需要从严格的软件工程管理的角度进行认真规划，有步骤有逻辑地进行开发。对于大型网站来 说，所采用的技术涉及面极其广泛，从硬件到软件、编程语言、数据库、Web服务器、防火墙等各个领域都有了很高的要求，已经不是原来简单的html静态网 站所能比拟的。以著名的Yahoo!为例，他们的每一个大型网站工程都需要大量相应专业人员的参与。  <br /><br />(五) 页面静态化  <br />&nbsp;&nbsp;&nbsp;&nbsp;   可不要小看纯静态化的HTML页面！其实在很多情况下，HTML往往意味着&#8220;效率最高、消耗最小&#8221;，所以我们尽可能使我们的网站上的页面采用静态页面来实 现。但是，对于大量内容并且频繁更新的网站，我们无法全部手动实现，因此可以开发相应的自动化更新工具，例如我们常见的信息发布系统CMS。像我们经常访 问的各个门户站点的新闻频道，甚至他们的其他频道，都是通过信息发布系统来管理和实现的。信息发布系统可以实现最简单的信息录入自动生成静态页面，还能具 备频道管理、权限管理、自动抓取等功能，对于一个大型网站来说，拥有一套高效、可管理的CMS是必不可少的。  <br /><br />(六) 存储问题 <br />&nbsp;&nbsp;&nbsp;&nbsp; 存储也是一个大问题，一种是小文件的存储，比如图片这类；另一种是大文件的存储，比如搜索引擎的索引。  <br />大 家知道，对于Web服务器来说，不管是Apache、IIS还是其他容器，图片是最消耗资源的，于是我们有必要将图片与页面进行分离，这是基本上大型网站 都会采用的策略，他们都有独立的图片服务器，甚至很多台图片服务器。这样的架构可以降低提供页面访问请求的服务器系统压力，并且可以保证系统不会因为图片 问题而崩溃，在应用服务器和图片服务器上，可以进行不同的配置优化以保证更高的系统消耗和执行效率。<br /><br />(七)  数据库技术&#8212;集群和库表散列  <br />&nbsp;&nbsp;&nbsp;&nbsp; 对于大型网站而言，使用大型的数据库服务器是必须的事情。但是，在面对大量访问的时候，数据库的瓶颈仍然会显现出来，这时一台数据库将很快无法满足应用，于是我们需要借助于数据库集群或者库表散列技术。<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;  在数据库集群方面，很多数据库厂商都有自己的解决方案，Oracle、Sybase、SQL   Server等都有很好的方案，常用的MySQL提供的Master/Slave也是类似的方案。因此，你使用了什么样的数据库，就参考相应的解决方案来 实施即可。  <br /><br />&nbsp;&nbsp;&nbsp;&nbsp;  上面提到的数据库集群由于在架构、成本、扩张性方面都会受到所采用数据库类型的限制，于是我们需要从应用程序的角度来考虑改善系统架构，其中，库表散列是 常用并且最有效的解决方案。我们在应用程序中安装业务和应用或者功能模块将数据库进行分离，不同的模块对应不同的数据库或者表，再按照一定的策略对某个页 面或者功能进行更小的数据库散列，比如用户表，按照用户ID进行表散列，这样就能够低成本的提升系统的性能并且有很好的扩展性。在这一方面一个现成的例子 就是搜狐。它的论坛就是采用了这样的架构，将论坛的用户、设置、帖子等信息进行数据库分离，然后对帖子、用户按照板块和ID进行散列数据库和表，最终可以 在配置文件中进行简单的配置便能让系统随时增加一台低成本的数据库进来补充系统性能。  <br /><br />(八) 缓存策略  <br />&nbsp;&nbsp;&nbsp;&nbsp;  这绝对不单指低级的缓存技术相关的编程，应从整个架构角度着眼，深入研究Web服务器、数据库服务器的各层级的缓冲策略，最后才是低级的缓冲技术的编程。 不同的Web服务器、数据库服务器及Web编程语言都有自己不同的缓冲策略。例如数据库存储方面，SQL  Serve  2005中的主动式缓存机制，Oracle数据的cache   group技术，Hibernate的缓存包括Session的缓存和SessionFactory的缓存；Web服务器方面，Apache提供了自己的 缓存模块，也可以使用外加的Squid模块进行缓存，这两种方式均可以有效的提高Apache的访问响应能力，IIS缓冲器技术；至于web开发语言，所 用缓存技术更存在很大不同，例如ASP.NET   2.0中提出了两种缓存应用程序数据和缓存服务页输出的策略，这两种缓存技术相互独立但不相互排斥，PHP有Pear的Cache模块，等等。 <br /><br />(九)  镜像  <br />&nbsp;&nbsp;&nbsp;&nbsp;   镜像是大型网站常采用的提高性能和数据安全性的方式，镜像的技术可以解决不同网络接入商和地域带来的用户访问速度差异。在镜像的细节技术方面，这里不阐述 太深，有很多专业的现成的解决架构和产品可选。也有廉价的通过软件实现的思路，比如Linux上的rsync等工具。  <br /><br />(十) 负载均衡 <br />&nbsp;&nbsp;&nbsp;&nbsp; 负载均衡将是大型网站解决高负荷访问和大量并发请求采用的终极解决办法。  <br />负载均衡技术发展了多年，有很多专业的服务提供商和产品可以选择，基于LAMP解决方案的Lighttped+Squid是相当不错的解决负载均衡和加速系统的有效方式。<br /><br />(十一)  硬件四层交换  <br />&nbsp;&nbsp;&nbsp;&nbsp;   第四层交换使用第三层和第四层信息包的报头信息，根据应用区间识别业务流，将整个区间段的业务流分配到合适的应用服务器进行处理。第四层交换功能就象是虚    IP，指向物理服务器。它传输的业务服从的协议多种多样，有HTTP、FTP、NFS、Telnet或其他协议。这些业务在物理服务器基础上，需要复杂的 载量平衡算法。在IP世界，业务类型由终端TCP或UDP端口地址来决定，在第四层交换中的应用区间则由源端和终端IP地址、TCP和UDP端口共同决 定。<br /><br />&nbsp;&nbsp;&nbsp;&nbsp; 在硬件四层交换产品领域，有一些知名的产品可以选择，比如Alteon、F5等，这些产品很昂贵，但是物有所值，能够提供非常优秀的性能和很灵活的管理能力。Yahoo中国当初接近2000台服务器使用了三四台Alteon就搞定了。<br />(十二)  软件四层交换  <br />&nbsp;&nbsp;&nbsp;&nbsp; 大家知道了硬件四层交换机的原理后，基于OSI模型来实现的软件四层交换也就应运而生，这样的解决方案实现的原理一致，不过性能稍差。但是满足一定量的压力还是游刃有余的。<br />&nbsp;&nbsp;&nbsp;&nbsp; 一个典型的使用负载均衡的策略就是，在软件或者硬件四层交换的基础上搭建squid集群，这种思路在很多大型网站包括搜索引擎上被采用，这样的架构低成本、高性能还有很强的扩张性，随时往架构里面增减节点都非常容易。  <br /><br />(十三) 软件投资问题  <br />&nbsp;&nbsp;&nbsp;&nbsp;   据报导，目前国内除了一些上市企业和特别大知名大公司以外，很少有企业在成本中考虑正版软件的购置费用。这种思维极有可能给中国互联网带来噩梦。如果一些 公司真正面临软件资金方面的困难，完全可以考虑使用开源世界的LAMP解决方案（Linux＋Apache＋MySQL＋Perl、PHP或者   Python Web编程语言）；否则，随着我国加入WTO范围的不断扩大，盗版打击必然越来越严。因此，&#8220;苟且偷生&#8221;必将自食其果。  <br /><br />&nbsp;&nbsp;&nbsp;&nbsp; 另外，随着网络带宽日渐提升，WEB  2.0技术必将影响到网络世界的几乎每一个角落。因此，如何积聚技术人员进行技术攻关并进一步加强安全防范也成为一个日益严峻的问题，宜尽早纳入到公司的议事日程。  <br />&nbsp;&nbsp;  <br /><strong>四、 总结</strong>  <br />&nbsp;&nbsp;&nbsp;&nbsp; 中国电子商务真正理性发展的一个标志，是大量的传统企业实实在在地开始用互联网来处理商务、做生意，而现在这样的浪潮已经开始。北京发行集团，联合SINA、6688.com等单位共同推出的网上虚拟书店&#8212;新新书店就是这样的一个标志。  <br />&nbsp;&nbsp;&nbsp;&nbsp;  随着网络带宽日渐提升，随着网络理念和WEB   2.0技术的断深入人心，各种B2B、B2C、C2C等电子商务模式很可能以立体交叉方式整合到各种大型商务网站中来。因此，作为公司的技术人员，作为临 危救驾的&#8220;白衣骑士&#8221;，如何应对海量存储、海量访问问题，海量信息检索的问题，日益严峻的安全问题，等等，已经刻不容缓。<img src="http://cnc.imgcache.qq.com/ac/b.gif"  alt="" /></div><img src ="http://www.blogjava.net/wealupa/aggbug/381717.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wealupa/" target="_blank">常言笑</a> 2012-06-28 14:37 <a href="http://www.blogjava.net/wealupa/archive/2012/06/28/381717.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>大型网站架构技术方案集锦</title><link>http://www.blogjava.net/wealupa/archive/2012/06/28/381716.html</link><dc:creator>常言笑</dc:creator><author>常言笑</author><pubDate>Thu, 28 Jun 2012 06:35:00 GMT</pubDate><guid>http://www.blogjava.net/wealupa/archive/2012/06/28/381716.html</guid><wfw:comment>http://www.blogjava.net/wealupa/comments/381716.html</wfw:comment><comments>http://www.blogjava.net/wealupa/archive/2012/06/28/381716.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wealupa/comments/commentRss/381716.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wealupa/services/trackbacks/381716.html</trackback:ping><description><![CDATA[<div><div id="cnblogs_post_body"><p>1. PlentyOfFish 网站架构学习</p> <p><a href="http://www.dbanotes.net/arch/plentyoffish_arch.html">http://www.dbanotes.net/arch/plentyoffish_arch.html</a></p> <p>采取 Windows 技术路线的 Web 2.0 站点并不多，除了 MySpace ，另外就是这个 PlentyOfFish。这个站点提供  &#8220;Online Dating&#8221; 服务。一个令人津津乐道的、惊人的数据是这个只有一个人(创建人Markus Frind）的站点价值 10  亿，估计要让很多人眼热，更何况 Markus Frind 每天只用两个小时打理网站&#8211;可操作性很强嘛。</p> <p>2. 从LiveJournal后台发展看 大型网站系统架构以及性能优化方法</p> <p><a href="http://www.example.net.cn/archives/2006/03/olivejournaloio.html">http://www.example.net.cn/archives/2006/03/olivejournaloio.html</a></p> <p>LiveJournal是99年始于校园中的项目，几个人出于爱好做了这样一个应用，以实现以下功能：</p> <p>* 博客，论坛</p> <p>* 社会性网络，找到朋友</p> <p>* 聚合，把朋友的文章聚合在一起</p> <p>LiveJournal采用了大量的开源软件，甚至它本身也是一个开源软件。</p> <p>在上线后，LiveJournal实现了非常快速的增长：</p> <p>* 2004年4月份：280万注册用户。</p> <p>* 2005年4月份：680万注册用户。</p> <p>* 2005年8月份：790万注册用户。</p> <p>* 达到了每秒钟上千次的页面请求及处理。</p> <p>* 使用了大量MySQL服务器。</p> <p>* 使用了大量通用组件。</p> <p>3. YouTube 的架构扩展</p> <p><a href="http://www.dbanotes.net/opensource/youtube_web_arch.html">http://www.dbanotes.net/opensource/youtube_web_arch.html</a></p> <p>在西雅图扩展性的技术研讨会上，YouTube 的 Cuong Do 做了关于 YouTube Scalability 的报告。视频内容在 Google Video 上有(地址)，可惜国内用户看不到。</p> <p>Kyle Cordes 对这个视频中的内容做了介绍。里面有不少技术性的内容。值得分享一下。(Kyle Cordes 的介绍是本文的主要来源)</p> <p>4. WikiPedia 技术架构学习分享</p> <p><a href="http://www.dbanotes.net/opensource/wikipedia_arch.html">http://www.dbanotes.net/opensource/wikipedia_arch.html</a></p> <p>维基百科(WikiPedia.org)位列世界十大网站，目前排名第八位。这是开放的力量。</p> <p>来点直接的数据：</p> <p>* 峰值每秒钟3万个 HTTP 请求</p> <p>* 每秒钟 3Gbit 流量, 近乎375MB</p> <p>* 350 台 PC 服务器</p> <p>5. Tailrank 网站架构</p> <p><a href="http://www.dbanotes.net/review/tailrank_arch.html">http://www.dbanotes.net/review/tailrank_arch.html</a></p> <p>每天数以千万计的 Blog 内容中，实时的热点是什么? Tailrank 这个 Web 2.0 Startup 致力于回答这个问题。</p> <p>专门爆料网站架构的 Todd Hoff 对 Kevin Burton 进行了采访。于是我们能了解一下 Tailrank  架构的一些信息。每小时索引 2400 万的 Blog 与 Feed，内容处理能力为 160-200Mbps，IO  写入大约在10-15MBps。每个月要处理 52T 之多的原始数据。Tailrank 所用的爬虫现在已经成为一个独立产品：spinn3r。</p> <p>6. LinkedIn 架构笔记</p> <p><a href="http://www.dbanotes.net/arch/linkedin.html">http://www.dbanotes.net/arch/linkedin.html</a></p> <p>LinkedIn 雇员有 180 个，在 Web 2.0 公司中算是比较多的，不过人家自从 2006 年就盈利了，这在 Web 2.0 站点中可算少的。用户超过 1600 万，现在每月新增 100 万，50％ 会员来自海外(中国用户不少，也包括我).</p> <p>7. Yahoo！社区架构</p> <p><a href="http://www.dbanotes.net/arch/yahoo_arch.html">http://www.dbanotes.net/arch/yahoo_arch.html</a></p> <p>旧金山举行的 QCon 会议带给我们很多新鲜的信息。虽然没机会参加，但是看看各个网站&#8221;晒架构&#8221;也是个比较过瘾的事情。请参观并收藏这个页面：Architectures you&#8217;ve always wondered about。</p> <p>8. Craigslist 的数据库架构</p> <p><a href="http://www.dbanotes.net/database/craigslist_database_arch.html">http://www.dbanotes.net/database/craigslist_database_arch.html</a></p> <p>Craigslist 绝对是互联网的一个传奇公司。根据以前的一则报道：</p> <p>每月超过 1000 万人使用该站服务，月浏览量超过 30 亿次，(Craigslist每月新增的帖子近 10 亿条??)网站的网页数量在以每年近百倍的速度增长。Craigslist 至今却只有 18 名员工(现在可能会多一些了)。</p> <p>9. Fotolog.com 的技术信息拾零</p> <p><a href="http://www.dbanotes.net/review/fotolog_arch.html">http://www.dbanotes.net/review/fotolog_arch.html</a></p> <p>尽管是世界上最大的图片服务网站, Fotolog.com 在国内的名气并不是很响亮, 每当提到图片服务, 很多人第一个会想起  Flickr. 但实际上 Fotolog 也的确是很猛的, Alexa 上的排名一直在 Flickr 前面, 目前注册用户超过 1100 万.  而前不久也卖了一个好价钱, 9000 万美金. 算下来的话, 1 个注册用户大约 9 美金. Yupoo  的刘平阳可以偷着算算自己的网站如果卖给老外是怎样一个价格了.</p> <p>10. Digg 网站架构</p> <p><a href="http://www.dbanotes.net/arch/digg_arch_cache_and_shard.html">http://www.dbanotes.net/arch/digg_arch_cache_and_shard.html</a></p> <p>Digg 工程师采用 LAMP (Linux, Apache, MySQL and PHP) 模式。这个 Alexa 排名在 100  左右的、自我估价 1.5 亿美金的站点目前有超过 100 台的 PC 服务器(足够少了)，可以粗略分成三个部分：数据库服务器，Web  服务器，搜索服务器。</p> <p>11. Amazon 的 Dynamo 架构</p> <p><a href="http://www.dbanotes.net/techmemo/amazon_dynamo.html">http://www.dbanotes.net/techmemo/amazon_dynamo.html</a></p> <p>我在 DBAnotes.net 上记录过不少比较大的网站架构分析(eg: eBay [1], eBay [2]) ，Amazon  一直找不到太多的资料。国庆期间读到了一篇关于 Amazon Dynamo 的论文，非常精彩。Amazon Dynamo  这个高可用、可扩展存储体系支撑了Amazon 不少核心服务.</p> <p>12. 财帮子（caibangzi.com）网站架构</p> <p><a href="http://www.dbanotes.net/arch/caibangzi_web_arch.html">http://www.dbanotes.net/arch/caibangzi_web_arch.html</a></p> <p>财帮子(caibangzi.com) 定位在&#8221;基金理财社区&#8221;。是国内访问量最大的基于 Ruby on rails 的 startup  项目。&#8220;理财&#8221;这个词据说是光大银行发明的，且不去管，不可否认的是，目前国内&#8221;理财&#8221;是个很有潜力的切入点。财帮子网站潜在用户群还是很大的。</p> <p>13. 了解一下 Technorati 的后台数据库架构</p> <p><a href="http://www.dbanotes.net/web/technorati_db_arch.html">http://www.dbanotes.net/web/technorati_db_arch.html</a></p> <p>目前处理着大约 10Tb 核心数据, 分布在大约 20 台机器上.通过复制, 多增加了 100Tb 数据, 分布在 200 台机器上.  每天增长的数据 1TB. 通过 SOA 的运用, 物理与逻辑的访问相隔离,似乎消除了数据库的瓶颈. 值得一提的是,  该扩展过程始终是利用普通的硬件与开源软件来完成的. 毕竟 , Web 2.0 站点都不是烧钱的主. 从数据量来看，这绝对是一个相对比较大的  Web 2.0 应用.</p> <p>14. 说说大型高并发高负载网站的系统架构</p> <p><a href="http://www.toplee.com/blog/?p=71">http://www.toplee.com/blog/?p=71</a></p> <p>我在CERNET做过拨号接入平台的搭建，而后在Yahoo&amp;3721从事过搜索引擎前端开发，又在MOP处理过大型社区猫扑大杂烩的架构 升级等工作，同时自己接触和开发过不少大中型网站的模块，因此在大型网站应对高负载和并发的解决方案上有一些积累和经验，可以和大家一起探讨一下。</p> <p>15. 大型高负载网站架构 的感想</p> <p><a href="http://atman.memoab.com/articles/194">http://atman.memoab.com/articles/194</a></p> <p>昨日认识了位健谈的IT人，原在verycd作系统管理的叶宁(这哥们现飘泊去见首都人民了).</p> <p>以前sweater给我介绍的他写的《大型高负载网站架构和应用初探》, 他总结了很多信息和数据，感谢叶宁的辛劳成果. 这里我也想就此PPT写些自己的感想. </p></div></div><img src ="http://www.blogjava.net/wealupa/aggbug/381716.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wealupa/" target="_blank">常言笑</a> 2012-06-28 14:35 <a href="http://www.blogjava.net/wealupa/archive/2012/06/28/381716.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>大型网站架构设计</title><link>http://www.blogjava.net/wealupa/archive/2012/06/28/381707.html</link><dc:creator>常言笑</dc:creator><author>常言笑</author><pubDate>Thu, 28 Jun 2012 05:34:00 GMT</pubDate><guid>http://www.blogjava.net/wealupa/archive/2012/06/28/381707.html</guid><wfw:comment>http://www.blogjava.net/wealupa/comments/381707.html</wfw:comment><comments>http://www.blogjava.net/wealupa/archive/2012/06/28/381707.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wealupa/comments/commentRss/381707.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wealupa/services/trackbacks/381707.html</trackback:ping><description><![CDATA[<div><div fc05="" fc11="" nbw-blog="" ztag=""  js-fs2"=""><p style="text-indent: 2em;">按需提供大型网站的架构设计，具体包括：</p> <div><img alt="大型网站架构设计 - adyhpq - adyhpq的个人主页" style="margin: 0px 10px 0px 0px;" src="http://img.ph.126.net/BR6fmxenKbFga2FeA-TPzw==/3057944146985054952.jpg" /></div> <p style="text-indent: 2em;">&nbsp;<br /></p> <p style="text-indent: 2em;">A. 提供后台数据库设计：根据业务需求的理解，针对指定的数据库（涵盖Oracle,MySql,SqlServer,DB2）提供网站项目的后台数据库设计。</p> <p style="text-indent: 2em;">后台数据库的设计是整个网站最重要的环节，其结构定义通常确定了后台业务数据的存储方式以及 绝大部分后台数据访问模型。对大型网站而言，由于其需要支撑的负荷很大，数据库设计将关系到数据储存量，数据访问效率，缓存效率，数据安全等多个方面，大 型网站的数据库设计原则与普通企业应用的设计原则有许多区别，需要经验丰富的架构师才能胜任。</p> <p style="text-indent: 2em;">提供后台持久层设计：持久层设计是在后台数据库设计的基础上，根据具体编程语言，根据网站访问特征具体设计的编程框架。设计目标将兼顾处理效率和代码的可维护性、可理解性（如面向对象）。</p> <p style="text-indent: 2em;">B. 提供缓存设计：根据业务需求，结合后台数据库设计和后台持久层设计，提供网站的缓存设计方案。具体包括前端缓存，共享数据缓存，分布式缓存。</p> <p style="text-indent: 2em;">所谓前端缓存，指把网页上短期内不太变化的内容、根据访问效率评估，通过片段形式以一定策略缓存起来，从而减少后台内容生成的时间，提升网站的响应效率和节省服务器的处理资源占用。</p> <p style="text-indent: 2em;">所谓共享数据缓存，指把后台中公共的数据根据访问频度和更新频度以一定策略在服务器缓存起来，避免每次使用都需要从数据库或磁盘提取。</p> <p style="text-indent: 2em;">所谓分布式缓存，指大型网站需要利用分布式的缓存来在多台集群机器之间共享某些处理结果内容。</p> <p style="text-indent: 2em;">C. 提供MVC（Model-View-Controller）框架设计：根据业务需求和网站特点提供合适的、高效的MVC处理框架。</p> <p style="text-indent: 2em;">MVC是Web应用前端的重要架构组成，网站交互的绝大部分内容将集中在这个部分，一套高效而易于扩展和使用的MVC框架是整个网站中重要组成。</p> <p style="text-indent: 2em;">D. 提供安全框架：根据业务需要和数据安全保护的需要，提供网站安全框架。</p> <p style="text-indent: 2em;">E. 提供SEO（Search Engine Optimize)方案：面向搜索引擎提供网站搜索优化方案。</p> <p style="text-indent: 2em;">F. 提供备份方案：根据业务需要提供针对不同平台的数据（代码、数据、用户资料）等备份方案。</p></div></div><img src ="http://www.blogjava.net/wealupa/aggbug/381707.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wealupa/" target="_blank">常言笑</a> 2012-06-28 13:34 <a href="http://www.blogjava.net/wealupa/archive/2012/06/28/381707.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>大型网站架构不得不考虑的10个问题</title><link>http://www.blogjava.net/wealupa/archive/2012/06/28/381705.html</link><dc:creator>常言笑</dc:creator><author>常言笑</author><pubDate>Thu, 28 Jun 2012 05:26:00 GMT</pubDate><guid>http://www.blogjava.net/wealupa/archive/2012/06/28/381705.html</guid><wfw:comment>http://www.blogjava.net/wealupa/comments/381705.html</wfw:comment><comments>http://www.blogjava.net/wealupa/archive/2012/06/28/381705.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wealupa/comments/commentRss/381705.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wealupa/services/trackbacks/381705.html</trackback:ping><description><![CDATA[<div><p>这里的大型网站架构只包括高互动性高交互性的数据型大型网站，基于大家众所周知的原因，我们就不谈新闻类和一些依靠HTML静态化就可以实现的架构 了，我们以高负载高数据交换高数据流动性的网站为例，比如海内，开心网等类似的web2.0系列架构。我们这里不讨论是PHP还是JSP或者.NET环 境，我们从架构的方面去看问题，实现语言方面并不是问题，语言的优势在于实现而不是好坏，不论你选择任何语言，架构都是必须要面对的。</p> <p>这里讨论一下大型网站需要注意和考虑的问题</p> <p><strong>1、海量数据的处理</strong> </p> <p>众所周知，对于一些相对小的站点来说，数据量并不是很大，select和update就可以解决我们面对的问题，本身负载量不是很大，最多再加几个 索引就可以搞定。对于大型网站，每天的数据量可能就上百万，如果一个设计不好的多对多关系，在前期是没有任何问题的，但是随着用户的增长，数据量会是几何 级的增长的。在这个时候我们对于一个表的select和update的时候(还不说多表联合查询)的成本的非常高的。</p> <p><strong>2、数据并发的处理</strong> </p> <p>在一些时候，2.0的CTO都有个尚方宝剑，就是缓存。对于缓存，在高并发高处理的时候也是个大问题。在整个应用程序下，缓存是全局共享的，然而在 我们进行修改的时候就，如果两个或者多个请求同时对缓存有更新的要求的情况下，应用程序会直接的死掉。这个时候，就需要一个好的数据并发处理策略以及缓存 策略。</p> <p>另外，就是数据库的死锁问题，也许平时我们感觉不到，死锁在高并发的情况下的出现的概率是非常高的，磁盘缓存就是一个大问题。</p> <p><strong>3、文件存贮的问题</strong> </p> <p>对于一些支持文件上传的2.0的站点，在庆幸硬盘容量越来越大的时候我们更多的应该考虑的是文件应该如何被存储并且被有效的索引。常见的方案是对文 件按照日期和类型进行存贮。但是当文件量是海量的数据的情况下，如果一块硬盘存贮了500个G的琐碎文件，那么维护的时候和使用的时候磁盘的Io就是一个 巨大的问题，哪怕你的带宽足够，但是你的磁盘也未必响应过来。如果这个时候还涉及上传，磁盘很容易就over了。</p> <p>也许用raid和专用存贮服务器能解决眼下的问题，但是还有个问题就是各地的访问问题，也许我们的服务器在北京，可能在云南或者新疆的访问速度如何解决?如果做分布式，那么我们的文件索引以及架构该如何规划。</p> <p>所以我们不得不承认，文件存贮是个很不容易的问题</p> <p><strong>4、数据关系的处理</strong> </p> <p>我们可以很容易的规划出一个符合第三范式的数据库，里面布满了多对多关系，还能用GUID来替换INDENTIFY COLUMN 但是，多对多关系充斥的2.0时代，第三范式是第一个应该被抛弃的。必须有效的把多表联合查询降到最低。</p> <p><strong>5、数据索引的问题</strong> </p> <p>众所周知，索引是提高数据库效率查询的最方面最廉价最容易实现的方案。但是，在高UPDATE的情况下，update和delete付出的成本会高的无法想想，笔者遇到过一个情况，在更新一个聚焦索引的时候需要10分钟来完成，那么对于站点来说，这些基本上是不可忍受的。</p> <p>索引和更新是一对天生的冤家，问题A，D，E这些是我们在做架构的时候不得不考虑的问题，并且也可能是花费时间最多的问题，</p> <p><strong>6、分布式处理</strong> </p> <p>对于2.0网站由于其高互动性，CDN实现的效果基本上为0，内容是实时更新的，我们常规的处理。为了保证各地的访问速度，我们就需要面对一个绝大的问题，就是如何有效的实现数据同步和更新，实现各地服务器的实时通讯有是一个不得不需要考虑的问题。</p> <p><strong>7、Ajax的利弊分析</strong> </p> <p>成也AJAX，败也AJAX，AJAX成为了主流趋势，突然发现基于XMLHTTP的post和get是如此的容易。客户端get或者post  到服务器数据，服务器接到数据请求之后返回来，这是一个很正常的AJAX请求。但是在AJAX处理的时候，如果我们使用一个抓包工具的话，对数据返回和处 理是一目了然。对于一些计算量大的AJAX请求的话，我们可以构造一个发包机，很容易就可以把一个webserver干掉。</p> <p><strong>8、数据安全性的分析</strong> </p> <p>对于HTTP协议来说，数据包都是明文传输的，也许我们可以说我们可以用加密啊，但是对于G问题来说的话，加密的过程就可能是明文了(比如我们知道 的QQ，可以很容易的判断他的加密，并有效的写一个跟他一样的加密和解密方法出来的)。当你站点流量不是很大的时候没有人会在乎你，但是当你流量上来之 后，那么所谓的外挂，所谓的群发就会接踵而来(从qq一开始的群发可见端倪)。也许我们可以很的意的说，我们可以采用更高级别的判断甚至HTTPS来实 现，注意，当你做这些处理的时候付出的将是海量的database，io以及CPU的成本。对于一些群发，基本上是不可能的。笔者已经可以实现对于百度空 间和qq空间的群发了。大家愿意试试，实际上并不是很难。</p> <p><strong>9、数据同步和集群的处理的问题</strong> </p> <p>当我们的一台databaseserver不堪重负的时候，这个时候我们就需要做基于数据库的负载和集群了。而这个时候可能是最让人困扰的的问题 了，数据基于网络传输根据数据库的设计的不同，数据延迟是很可怕的问题，也是不可避免的问题，这样的话，我们就需要通过另外的手段来保证在这延迟的几秒或 者更长的几分钟时间内，实现有效的交互。比如数据散列，分割，内容处理等等问题</p> <p><strong>10、数据共享的渠道以及OPENAPI趋势</strong> </p> <p>Openapi已经成为一个不可避免的趋势，从google，facebook，myspace到海内校内，都在考虑这个问题，它可以更有效的留住 用户并激发用户的更多的兴趣以及让更多的人帮助你做最有效的开发。这个时候一个有效的数据共享平台，数据开放平台就成为必不可少的途径了，而在开放的接口 的情况保证数据的安全性和性能，又是一个我们必须要认真思考的问题了。</p></div><img src ="http://www.blogjava.net/wealupa/aggbug/381705.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wealupa/" target="_blank">常言笑</a> 2012-06-28 13:26 <a href="http://www.blogjava.net/wealupa/archive/2012/06/28/381705.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>