??xml version="1.0" encoding="utf-8" standalone="yes"?>91嫩草私人成人亚洲影院,亚洲精华国产精华精华液,亚洲va成无码人在线观看http://m.tkk7.com/jlin/category/54694.htmlzh-cnWed, 21 Oct 2015 19:43:49 GMTWed, 21 Oct 2015 19:43:49 GMT60一致性Hash法在Redis分布式中的??http://m.tkk7.com/jlin/archive/2015/10/20/427834.htmlflyflyTue, 20 Oct 2015 07:51:00 GMThttp://m.tkk7.com/jlin/archive/2015/10/20/427834.htmlhttp://m.tkk7.com/jlin/comments/427834.htmlhttp://m.tkk7.com/jlin/archive/2015/10/20/427834.html#Feedback0http://m.tkk7.com/jlin/comments/commentRss/427834.htmlhttp://m.tkk7.com/jlin/services/trackbacks/427834.html׃redis是单点,但是目中不可避免的会用多台Redis~存服务器,那么怎么把缓存的Key均匀的映到多台Redis服务器上Q且随着~存服务器的增加或减时做到最化的减缓存Key的命中率呢?q样需要我们自己实现分布式?/span>

  Memcached对大家应该不陌生Q通过把Key映射到Memcached Server上,实现快速读取。我们可以动态对其节点增加,q未影响之前已经映射到内存的Key与memcached Server之间的关p,q就是因Z用了一致性哈希?br />因ؓMemcached的哈希策略是在其客户端实现的Q因此不同的客户端实C有区别,以Spymemcache、XmemcacheZQ都是用了KETAMA作ؓ其实现?/p>

  因此Q我们也可以使用一致性hash法来解决Redis分布式这个问题。在介绍一致性hash法之前Q先介绍一下我之前想的一个方法,怎么把Key均匀的映到多台Redis Server上?/p>

  ׃LZ水^有限且对Redis研究的不深,文中有写的不对的地方h正?/strong>

Ҏ一

该方案是前几天想的一个方法,主要思\是通过对缓存Key中的字母和数字的ascii码值求sumQ该sum值对Redis ServerL取余得到的数字即Key映射到的Redis ServerQ该Ҏ有一个很大的~陷是当Redis Server增加或减时Q基本上所有的Key都映不到对应的的Redis Server了。代码如下:

复制代码
    /// <summary>         /// Ҏ~存的Key映射对应的Server         /// </summary>         /// <param name="Key"></param>         /// <returns></returns>         public static RedisClient GetRedisClientByKey(string Key)         {             List<RedisClientInfo> RedisClientList = new List<RedisClientInfo>();             RedisClientList.Add(new RedisClientInfo() { Num = 0, IPPort = "127.0.0.1:6379" });             RedisClientList.Add(new RedisClientInfo() { Num = 1, IPPort = "127.0.0.1:9001" });              char[] charKey = Key.ToCharArray();             //记录Key中的所有字母与数字的ascii码和             int KeyNum = 0;             //记录余数             int Num = 0;             foreach (var c in charKey)             {                 if ((c >= 'a' && 'z' >= c) || (c >= 'A' && 'Z' >= c))                 {                     System.Text.ASCIIEncoding asciiEncoding = new System.Text.ASCIIEncoding();                     KeyNum = KeyNum + (int)asciiEncoding.GetBytes(c.ToString())[0];                 }                 if (c >= '1' && '9' >= c)                 {                     KeyNum += Convert.ToInt32(c.ToString());                 }             }             Num = KeyNum % RedisClientList.Count;             return new RedisClient(RedisClientList.Where(it => it.Num == Num).First().IPPort);         }         //Redis客户端信?/span>         public class RedisClientInfo         {             //Redis Server~号             public int Num { get; set; }             //Redis Server IP地址和端口号             public string IPPort { get; set; }         }
复制代码

Ҏ?/h2>

1、分布式实现

通过key做一致性哈希,实现key对应redisl点的分布?/p>

一致性哈希的实现Q?/p>

  1. hashD:通过支持MD5与MurmurHash两种计算方式Q默认是采用MurmurHashQ高效的hash计算?/li>
  2. 一致性的实现Q通过java的TreeMap来模拟环状结构,实现均匀分布

什么也不多说了Q直接上代码吧,LZ也是只知道点皮毛Q代码中q有一些看不懂的地方,留着以后慢慢琢磨

复制代码
public class KetamaNodeLocator     {         //原文中的JAVAcTreeMap实现了ComparatorҎQ这里我囄事,直接用了net下的SortedListQ其中Comparer接口ҎQ?/span>         private SortedList<long, string> ketamaNodes = new SortedList<long, string>();         private HashAlgorithm hashAlg;         private int numReps = 160;         //此处参数与JAVA版中有区别,因ؓ使用的静态方法,所以不再传递HashAlgorithm alg参数         public KetamaNodeLocator(List<string> nodes/*Qint nodeCopies*/)         {             ketamaNodes = new SortedList<long, string>();             //numReps = nodeCopies;             //Ҏ有节点,生成nCopies个虚拟结?/span>             foreach (string node in nodes)             {                 //每四个虚拟结点ؓ一l?/span>                 for (int i = 0; i < numReps / 4; i++)                 {                     //getKeyForNodeҎl虚拟结点得到惟一名称                      byte[] digest = HashAlgorithm.computeMd5(node + i);                     /** Md5是一?6字节长度的数l,?6字节的数l每四个字节一l,分别对应一个虚拟结点,q就是ؓ什么上面把虚拟l点四个划分一l的原因*/                     for (int h = 0; h < 4; h++)                     {                         long m = HashAlgorithm.hash(digest, h);                         ketamaNodes[m] = node;                     }                 }             }         }         public string GetPrimary(string k)         {             byte[] digest = HashAlgorithm.computeMd5(k);             string rv = GetNodeForKey(HashAlgorithm.hash(digest, 0));             return rv;         }         string GetNodeForKey(long hash)         {             string rv;             long key = hash;             //如果扑ֈq个节点Q直接取节点Q返?               if (!ketamaNodes.ContainsKey(key))             {                 //得到大于当前key的那个子MapQ然后从中取出第一个keyQ就是大于且d最q的那个key 说明详见: http://www.javaeye.com/topic/684087                 var tailMap = from coll in ketamaNodes                               where coll.Key > hash                               select new { coll.Key };                 if (tailMap == null || tailMap.Count() == 0)                     key = ketamaNodes.FirstOrDefault().Key;                 else                     key = tailMap.FirstOrDefault().Key;             }             rv = ketamaNodes[key];             return rv;         }     }     public class HashAlgorithm     {         public static long hash(byte[] digest, int nTime)         {             long rv = ((long)(digest[3 + nTime * 4] & 0xFF) << 24)                     | ((long)(digest[2 + nTime * 4] & 0xFF) << 16)                     | ((long)(digest[1 + nTime * 4] & 0xFF) << 8)                     | ((long)digest[0 + nTime * 4] & 0xFF);             return rv & 0xffffffffL; /* Truncate to 32-bits */         }         /**          * Get the md5 of the given key.          */         public static byte[] computeMd5(string k)         {             MD5 md5 = new MD5CryptoServiceProvider();              byte[] keyBytes = md5.ComputeHash(Encoding.UTF8.GetBytes(k));             md5.Clear();             //md5.update(keyBytes);             //return md5.digest();             return keyBytes;         }     }
复制代码

2、分布式试

1、假设有两个serverQ?001?002Q@环调?0ơ看看KeyD不能均匀的映到server上,代码如下Q?/p>

复制代码
    static void Main(string[] args)         {             //假设的server             List<string> nodes = new List<string>() { "0001","0002" };             KetamaNodeLocator k = new KetamaNodeLocator(nodes);             string str = "";             for (int i = 0; i < 10; i++)             {                 string Key="user_" + i;                 str += string.Format("Key:{0}分配到的Server为:{1}\n\n", Key, k.GetPrimary(Key));             }                          Console.WriteLine(str);                         Console.ReadLine();                       }
复制代码

E序q行两次的结果如下,发现Key基本上均匀的分配到Server节点上了?/p>

2、我们在d一?003的server节点Q代码如下:

复制代码
  static void Main(string[] args)         {             //假设的server             List<string> nodes = new List<string>() { "0001","0002" ,"0003"};             KetamaNodeLocator k = new KetamaNodeLocator(nodes);             string str = "";             for (int i = 0; i < 10; i++)             {                 string Key="user_" + i;                 str += string.Format("Key:{0}分配到的Server为:{1}\n\n", Key, k.GetPrimary(Key));             }                          Console.WriteLine(str);                         Console.ReadLine();                       }
复制代码

E序q行两次的结果如下:

ҎW一ơ的q行l果发现只有user_5,user_7,user_9的缓存丢失,其他的缓存还可以命中?/p>

3、我们去掉server 0002Q运行两ơ的l果如下:

ҎW二ơ和本次q行l果发现 user_0,user_1,user_6 ~存丢失?/p>

l论

通过一致性hash法可以很好的解决Redis分布式的问题Q且当Redis server增加或减的时候,之前存储的缓存命中率q是比较高的?br />

http://www.cnblogs.com/lc-chenlong/p/4194150.html
http://www.cnblogs.com/lc-chenlong/p/4195033.html
http://www.cnblogs.com/lc-chenlong/p/3218157.html

本文参?/h2>

1?a target="_blank" style="color: #1d58d1; text-decoration: none;">http://blog.csdn.net/chen77716/article/details/5949166

2?a target="_blank" style="color: #1d58d1; text-decoration: none;">http://www.cr173.com/html/6474_2.html


?http://www.cnblogs.com/lc-chenlong/p/4195814.html?utm_source=tuicool&utm_medium=referral





fly 2015-10-20 15:51 发表评论
]]>应用于负载均衡的一致性哈希及java实现(?http://m.tkk7.com/jlin/archive/2015/10/19/427820.htmlflyflyMon, 19 Oct 2015 07:23:00 GMThttp://m.tkk7.com/jlin/archive/2015/10/19/427820.htmlhttp://m.tkk7.com/jlin/comments/427820.htmlhttp://m.tkk7.com/jlin/archive/2015/10/19/427820.html#Feedback0http://m.tkk7.com/jlin/comments/commentRss/427820.htmlhttp://m.tkk7.com/jlin/services/trackbacks/427820.html阅读全文

fly 2015-10-19 15:23 发表评论
]]>
高性能|站架构设计之缓存篇Q?Q? Redis 集群(?http://m.tkk7.com/jlin/archive/2015/10/14/427731.htmlflyflyWed, 14 Oct 2015 02:26:00 GMThttp://m.tkk7.com/jlin/archive/2015/10/14/427731.htmlhttp://m.tkk7.com/jlin/comments/427731.htmlhttp://m.tkk7.com/jlin/archive/2015/10/14/427731.html#Feedback0http://m.tkk7.com/jlin/comments/commentRss/427731.htmlhttp://m.tkk7.com/jlin/services/trackbacks/427731.html集群技术是构徏高性能|站架构的重要手D,试想在网站承受高q发讉K压力的同Ӟq需要从量数据中查询出满条g的数据,q快速响应,我们必然惛_的是数据进行切片,把数据根据某U规则放入多个不同的服务器节点,来降低单节点服务器的压力?/p>

上一我们讲C Redis 的主从复制技术,当实C多节点的 master-slave 后,我们也可以把它叫做集,但我们今天要讲的集群主要是利用切片技术来l徏的集?/p>

集群要实现的目的是要不同的 key 分散攄C同的 redis 节点Q这里我们需要一个规则或者算法,通常的做法是获取 key 的哈希|然后Ҏ节点数来求模Q但q种做法有其明显的弊端,当我们需要增加或减少一个节ҎQ会造成大量?key 无法命中Q这U比例是相当高的Q所以就有h提出了一致性哈希的概念?/p>

一致性哈希有四个重要特征Q?/p>

均衡性:也有人把它定义ؓq性,是指哈希的结果能够尽可能分布到所有的节点中去Q这样可以有效的利用每个节点上的资源?/p>

单调性:对于单调性有很多译让我非常的不解,而我惌的是当节Ҏ量变化时哈希的结果应可能的保护已分配的内容不会被重新分zֈ新的节点?/span>

分散性和负蝲Q这两个其实是差不多的意思,是要求一致性哈希算法对 key 哈希应尽可能的避免重复?/div>

但一致性哈希不是我们今天要介绍的重点,因ؓ Redis 引入另一U哈希槽Qhash slotQ的概念?/p>

Redis 集群中内|了 16384 个哈希槽Q当需要在 Redis 集群中放|一?key-value Ӟredis 先对 key 使用 crc16 法出一个结果,然后把结果对 16384 求余敎ͼq样每个 key 都会对应一个编号在 0-16383 之间的哈希槽Qredis 会根据节Ҏ量大致均{的哈希槽映射C同的节点?/p>

使用哈希槽的好处在于可以方便的d或移除节炏V?/p>

当需要增加节ҎQ只需要把其他节点的某些哈希槽挪到新节点就可以了;

当需要移除节ҎQ只需要把U除节点上的哈希槽挪到其他节点就行了Q?/p>

内部机制Q与我何qԌ对于我们来说Q在新增或移除节点的时候不要让我们先停掉所有的 redis 服务我就谢天谢地了,q点它做C?/p>

下面我们开始动手搭Z?redis 集群来体验一下?/p>

因ؓ我们要启动多?redis 实例Q虽然我们可以直接通过命o行来启动Q但始终是不怎么方便的,所以我们先来新Z个实例目录,分别?001Q?002Q?003Q目录名是 redis 实例的端口号?/p>

我这里已l徏好了目录Q然后我们把以前~译q和修改q的 redis-server、redis.confq两个文件分别拷贝到q三个目录里面,拯完之后就像这样子了:

我们打开 redis.conf 文gQؓ了简单v见,我们只保留下面几个配|项Q?/p>

daemonize yes
port 9001
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes

注意Qport 要修Ҏ对应目录的名字,也就是每个实例要有不同的端口?/p>

下面我们分别启动q三个实例:

zhaoguihuadediannao:~ zhaogh$ cd applications/dev/redis-cluster

zhaoguihuadediannao:redis-cluster zhaogh$ cd 9001

zhaoguihuadediannao:9001 zhaogh$ ./redis-server ./redis.conf

zhaoguihuadediannao:9003 zhaogh$ cd ../9002

zhaoguihuadediannao:9002 zhaogh$ ./redis-server ./redis.conf

zhaoguihuadediannao:9002 zhaogh$ cd ../9003

zhaoguihuadediannao:9003 zhaogh$ ./redis-server ./redis.conf

zhaoguihuadediannao:9003 zhaogh$ 

接下来我们来创徏集群Q让三个实例互相通讯Q?/p>

zhaoguihuadediannao:src zhaogh$ ./redis-trib.rb create --replicas 0 127.0.0.1:9001 127.0.0.1:9002 127.0.0.1:9003

>>> Creating cluster

Connecting to node 127.0.0.1:9001: OK

Connecting to node 127.0.0.1:9002: OK

Connecting to node 127.0.0.1:9003: OK

>>> Performing hash slots allocation on 3 nodes...

Using 3 masters:

127.0.0.1:9001

127.0.0.1:9002

127.0.0.1:9003

M: 92c9912cb1ccf657c886ecd839dd32c66efd8762 127.0.0.1:9001

   slots:0-5460 (5461 slots) master

M: b6d46fcb8b0e6ee373b09a4f2cbcec744d1a259b 127.0.0.1:9002

   slots:5461-10922 (5462 slots) master

M: 44ab30c7c589ffb15b9b04dd827c72cfaeedacb2 127.0.0.1:9003

   slots:10923-16383 (5461 slots) master

Can I set the above configuration? (type 'yes' to accept): yes

>>> Nodes configuration updated

>>> Assign a different config epoch to each node

>>> Sending CLUSTER MEET messages to join the cluster

Waiting for the cluster to join..

>>> Performing Cluster Check (using node 127.0.0.1:9001)

M: 92c9912cb1ccf657c886ecd839dd32c66efd8762 127.0.0.1:9001

   slots:0-5460 (5461 slots) master

M: b6d46fcb8b0e6ee373b09a4f2cbcec744d1a259b 127.0.0.1:9002

   slots:5461-10922 (5462 slots) master

M: 44ab30c7c589ffb15b9b04dd827c72cfaeedacb2 127.0.0.1:9003

   slots:10923-16383 (5461 slots) master

[OK] All nodes agree about slots configuration.

>>> Check for open slots...

>>> Check slots coverage...

[OK] All 16384 slots covered.

zhaoguihuadediannao:src zhaogh$ 

需要注意的是执?nbsp;redis-trib.rb 命o需?ruby 的支持,如果你没有安装可以先?nbsp;https://rubygems.org/gems/redis 下蝲Q然后离U安装?/p>

sudo gem install redis-3.0.7.gem --local

下面我们?redis 自带的客L试一下:

zhaoguihuadediannao:src zhaogh$ ./redis-cli -c -p 9001

127.0.0.1:9001> get testkey001

-> Redirected to slot [12786] located at 127.0.0.1:9003

(nil)

127.0.0.1:9003> set testkey002 testvalue002

-> Redirected to slot [401] located at 127.0.0.1:9001

OK

127.0.0.1:9001> get testkey002

"testvalue002"

127.0.0.1:9001> set testkey003 testvalue003

OK

127.0.0.1:9001> 

可以看到Q虽然我们第一ơ连接的?001端口Q当我们去获?testkey001 的时候,redis cluster 自动帮我们重定向?9003 ?/p>

当我们在 9003 讄 testkey002 Ӟredis cluster 又重定向?9001 ?/p>

fly 2015-10-14 10:26 发表评论
]]>Nginx配置文g详细说明http://m.tkk7.com/jlin/archive/2015/02/03/422720.htmlflyflyTue, 03 Feb 2015 15:00:00 GMThttp://m.tkk7.com/jlin/archive/2015/02/03/422720.htmlhttp://m.tkk7.com/jlin/comments/422720.htmlhttp://m.tkk7.com/jlin/archive/2015/02/03/422720.html#Feedback0http://m.tkk7.com/jlin/comments/commentRss/422720.htmlhttp://m.tkk7.com/jlin/services/trackbacks/422720.html在此记录下Nginx服务器nginx.conf的配|文件说? 部分注释攉与网l?

#q行用户
user www-data;   
#启动q程,通常讄成和cpu的数量相{?br />worker_processes  1;

#全局错误日志及PID文g
error_log  /var/log/nginx/error.log;
pid        /var/run/nginx.pid;

#工作模式及连接数上限
events {
    use   epoll;             #epoll是多路复用IO(I/O Multiplexing)中的一U方?但是仅用于linux2.6以上内核,可以大大提高nginx的性能
    worker_connections  1024;#单个后台worker processq程的最大ƈ发链接数
    # multi_accept on;
}

#讑֮http服务器,利用它的反向代理功能提供负蝲均衡支持
http {
     #讑֮mimecd,cd由mime.type文g定义
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;
    #讑֮日志格式
    access_log    /var/log/nginx/access.log;

    #sendfile 指o指定 nginx 是否调用 sendfile 函数Qzero copy 方式Q来输出文gQ对于普通应用,
    #必须设ؓ on,如果用来q行下蝲{应用磁盘IO重负载应用,可设|ؓ offQ以q盘与网lI/O处理速度Q降低系l的uptime.
    sendfile        on;
    #tcp_nopush     on;

    #q接时旉
    #keepalive_timeout  0;
    keepalive_timeout  65;
    tcp_nodelay        on;
   
    #开启gzip压羃
    gzip  on;
    gzip_disable "MSIE [1-6]\.(?!.*SV1)";

    #讑֮h~冲
    client_header_buffer_size    1k;
    large_client_header_buffers  4 4k;

    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;

    #讑֮负蝲均衡的服务器列表
     upstream mysvr {
    #weigth参数表示权|权D高被分配到的几率大
    #本机上的Squid开?128端口
    server 192.168.8.1:3128 weight=5;
    server 192.168.8.2:80  weight=1;
    server 192.168.8.3:80  weight=6;
    }


   server {
    #侦听80端口
        listen       80;
        #定义使用www.xx.com讉K
        server_name  www.xx.com;

        #讑֮本虚拟主机的讉K日志
        access_log  logs/www.xx.com.access.log  main;

    #默认h
    location / {
          root   /root;      #定义服务器的默认|站根目录位|?br />          index index.php index.html index.htm;   #定义首页索引文g的名U?/p>

          fastcgi_pass  www.xx.com;
         fastcgi_param  SCRIPT_FILENAME  $document_root/$fastcgi_script_name;
          include /etc/nginx/fastcgi_params;
        }

    # 定义错误提示面
    error_page   500 502 503 504 /50x.html; 
        location = /50x.html {
        root   /root;
    }

    #静态文Ӟnginx自己处理
    location ~ ^/(images|javascript|js|css|flash|media|static)/ {
        root /var/www/virtual/htdocs;
        #q期30天,静态文件不怎么更新Q过期可以设大一点,如果频繁更新Q则可以讄得小一炏V?br />        expires 30d;
    }
    #PHP 脚本h全部转发?FastCGI处理. 使用FastCGI默认配置.
    location ~ \.php$ {
        root /root;
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME /home/www/www$fastcgi_script_name;
        include fastcgi_params;
    }
    #讑֮查看Nginx状态的地址
    location /NginxStatus {
        stub_status            on;
        access_log              on;
        auth_basic              "NginxStatus";
        auth_basic_user_file  conf/htpasswd;
    }
    #止讉K .htxxx 文g
    location ~ /\.ht {
        deny all;
    }
    
     }
}

以上是一些基本的配置,使用Nginx最大的好处是负蝲均衡

如果要用负载均衡的?可以修改配置http节点如下Q?/p>

#讑֮http服务器,利用它的反向代理功能提供负蝲均衡支持
http {
     #讑֮mimecd,cd由mime.type文g定义
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;
    #讑֮日志格式
    access_log    /var/log/nginx/access.log;

    #省略上文有的一些配|节?/p>

    #。。。。。。。。。?/p>

    #讑֮负蝲均衡的服务器列表
     upstream mysvr {
    #weigth参数表示权|权D高被分配到的几率大
    server 192.168.8.1x:3128 weight=5;#本机上的Squid开?128端口
    server 192.168.8.2x:80  weight=1;
    server 192.168.8.3x:80  weight=6;
    }

   upstream mysvr2 {
    #weigth参数表示权|权D高被分配到的几率大

    server 192.168.8.x:80  weight=1;
    server 192.168.8.x:80  weight=6;
    }

   #W一个虚拟服务器
   server {
    #侦听192.168.8.x?0端口
        listen       80;
        server_name  192.168.8.x;

      #对aspx后缀的进行负载均衡请?br />    location ~ .*\.aspx$ {

         root   /root;      #定义服务器的默认|站根目录位|?br />          index index.php index.html index.htm;   #定义首页索引文g的名U?/p>

          proxy_pass  http://mysvr ;#h转向mysvr 定义的服务器列表

          #以下是一些反向代理的配置可删?

          proxy_redirect off;

          #后端的Web服务器可以通过X-Forwarded-For获取用户真实IP
          proxy_set_header Host $host;
          proxy_set_header X-Real-IP $remote_addr;
          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
          client_max_body_size 10m;    #允许客户端请求的最大单文g字节?br />          client_body_buffer_size 128k;  #~冲Z理缓冲用Lh的最大字节数Q?br />          proxy_connect_timeout 90;  #nginx跟后端服务器q接时旉(代理q接时)
          proxy_send_timeout 90;        #后端服务器数据回传时?代理发送超?
          proxy_read_timeout 90;         #q接成功后,后端服务器响应时?代理接收时)
          proxy_buffer_size 4k;             #讄代理服务器(nginxQ保存用户头信息的缓冲区大小
          proxy_buffers 4 32k;               #proxy_buffers~冲区,|页q_?2k以下的话Q这栯|?br />          proxy_busy_buffers_size 64k;    #高负荷下~冲大小Qproxy_buffers*2Q?br />          proxy_temp_file_write_size 64k;  #讑֮~存文g夹大,大于q个|从upstream服务器传

       }

     }
}



fly 2015-02-03 23:00 发表评论
]]>
Nginx+Tomcat+Memcached集群(?http://m.tkk7.com/jlin/archive/2015/02/01/422636.htmlflyflySun, 01 Feb 2015 15:19:00 GMThttp://m.tkk7.com/jlin/archive/2015/02/01/422636.htmlhttp://m.tkk7.com/jlin/comments/422636.htmlhttp://m.tkk7.com/jlin/archive/2015/02/01/422636.html#Feedback0http://m.tkk7.com/jlin/comments/commentRss/422636.htmlhttp://m.tkk7.com/jlin/services/trackbacks/422636.htmlTomcat集群session同步Ҏ有以下几U方式:

  • 使用tomcat自带的cluster方式Q多个tomcat间自动实时复制session信息Q配|v来很单。但q个Ҏ的效率比较低Q在大ƈ发下表现q不好。原理:http://zyycaesar.iteye.com/blog/296606
  • 利用nginx的基于访问ip的hash路由{略Q保证访问的ip始终被\由到同一个tomcat上,q个配置更简单。但如果应用是某一个局域网大量用户同时dQ这栯载均衡就没什么作用了?/li>
  • 利用nginx插g实现tomcat集群和session同步Qnginx-upstream-jvm-route-0.1.tar.gzQ是一?Nginx 的扩展模块,用来实现Z Cookie ?Session Sticky 的功能,可通过http://code.google.com/p/nginx-upstream-jvm-route/downloads/list获取?/li>
  • 利用memcached把多个tomcat的session集中理Q前端在利用nginx负蝲均衡和动静态资源分,在兼儡l水qx展的同时又能保证较高的性能?/li>

以下使用W四U方案,集群环境Q?/p>

1. nginx最新版本:1.5.7

2. tomcat版本Q?.0.37

3. memcached最新版本:1.4.15

4. session复制同步使用memcache-session-manager最新版本:1.6.5

5. pȝQCentOS6.3


一、Nginx安装

- centos6.3默认未安装gcc-c++Q先装gccQ?/p>

yum -y install gcc-c++

装完后记得rebootpȝ?/p>

- cd到安装目?/p>

cd /usr/lcoal/src

- 安装pcre?/p>

复制代码
cd /usr/local/src wget ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-8.21.tar.gz tar -zxvf pcre-8.21.tar.gz cd pcre-8.21 ./configure make make install
复制代码

如果wget下蝲不到的话Q去官网下蝲pcre-8.12.tar.gz包拷贝到src下?/p>

- 安装zlib?/p>

复制代码
cd /usr/local/src   wget http://zlib.net/zlib-1.2.8.tar.gz tar -zxvf zlib-1.2.8.tar.gz cd zlib-1.2.8 ./configure make make install
复制代码

- 安装ssl

cd /usr/local/src wget http://www.openssl.org/source/openssl-1.0.1c.tar.gz tar -zxvf openssl-1.0.1c.tar.gz

- 安装nginx

复制代码
cd nginx-1.5.7   ./configure --prefix=/usr/local/nginx/nginx \ --with-http_ssl_module \ --with-pcre=/usr/local/src/pcre-8.12 \ --with-zlib=/usr/local/src/zlib-1.2.8 \ --with-openssl=/usr/local/src/openssl-1.0.1c   make make install
复制代码

安装成功Qcd /usr/local/nginx/conf/nginx.confQ修攚w|文Ӟ

复制代码
http { ...     upstream localhost {         server    localhost:8081;         server    localhost:8082;         server    localhost:8083;     } ... }   location / {       root   html;       index  index.html index.htm;       proxy_pass   http://localhost;       proxy_redirect    off;       proxy_set_header   Host $host;       proxy_set_header   X-Real-IP $remote_addr;       proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;        client_max_body_size   10m;       client_body_buffer_size   128k;       proxy_connect_timeout   90;       proxy_send_timeout   90;       proxy_read_timeout   90;       proxy_buffer_size   4k;       proxy_buffers   4 32k;       proxy_busy_buffers_size   64k;       proxy_temp_file_write_size  64k;         }

 

复制代码

二、memcached安装

- memcached安装较简单,需要先libevent库:

复制代码
sudo yum install libevent libevent-devel  wget http://www.danga.com/memcached/dist/memcached-1.4.15.tar.gz tar zxf memcached-1.4.15.tar.gz cd memcached-1.4.15 ./configure make sudo make install
复制代码

安装成功Q默认安装在bin下)Q启动:

#-vv 控制台输?#-d 后台q行 /usr/local/bin/memcached -vv

启动后,可以telnet上去看下状态:

telnet 127.0.0.1 11211  stats

 

 

三、tomcat配置

1. 修改server.xml

复制代码
<Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm1">  ...  <Context path="" docBase="/demo/appserver/app/cluster" debug="0" reloadable="true" crossContext="true">       <Manager 
    className="de.javakaffee.web.msm.MemcachedBackupSessionManager" memcachedNodes="n1:192.168.2.43:11211"     requestUriIgnorePattern=".*\.(png|gif|jpg|css|js|ico|jpeg|htm|html)$"     sessionBackupAsync="false"     sessionBackupTimeout="1800000"     copyCollectionsForSerialization="false"     transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory" /> </Context>
复制代码

2. dmem和msm的依赖jar?/p>

couchbase-client-1.2.2.jar

javolution-5.4.3.1.jar

kryo-1.03.jar

kryo-serializers-0.10.jar

memcached-session-manager-1.6.5.jar

memcached-session-manager-tc6-1.6.5.jar

minlog-1.2.jar

msm-kryo-serializer-1.6.5.jar

reflectasm-0.9.jar

spymemcached-2.10.2.jar

注意点:

-msm1.6.5依赖了CouchbaseQ需要添加couchbase-client的jar包,否则启动会报Qjava.lang.NoClassDefFoundError: com/couchbase/client/CouchbaseClient?/p>

-tomcat6?使用不同msm支持包:memcached-session-manager-tc6-1.6.5.jar和memcached-session-manager-tc7-1.6.5.jarQ只可选一Q否则启动报错?/p>

-msm源码中的lib包版本太低:spymemcached-2.7.jar需要?.10.2Q否则启动tomcat报错Q?/p>

java.lang.NoSuchMethodError: net.spy.memcached.MemcachedClient.set(Ljava/lang/String;ILjava/lang/Object;)Lnet/spy/memcached/internal/OperationFuture;
at de.javakaffee.web.msm.BackupSessionTask.storeSessionInMemcached(BackupSessionTask.java:227)

kryo-serializers-0.8.jar需要?.10版本Q否则报错:

Caused by: java.lang.ClassNotFoundException: de.javakaffee.kryoserializers.DateSerializer


tomcat启动成功后可以去h面Qip端口会变化,session是不会变化的Q?/p>

 

memcached的状态可以看到同步session的操作日志:



fly 2015-02-01 23:19 发表评论
]]>
Nginx 与Tomcat 实现动静态分R负载均??http://m.tkk7.com/jlin/archive/2015/02/01/422635.htmlflyflySun, 01 Feb 2015 15:18:00 GMThttp://m.tkk7.com/jlin/archive/2015/02/01/422635.htmlhttp://m.tkk7.com/jlin/comments/422635.htmlhttp://m.tkk7.com/jlin/archive/2015/02/01/422635.html#Feedback0http://m.tkk7.com/jlin/comments/commentRss/422635.htmlhttp://m.tkk7.com/jlin/services/trackbacks/422635.htmlNginx 与Tomcat 实现动静态分R负载均?/a>

一QNginx介:

   Nginx一个高性能的HTTP和反向代理服务器Q?nbsp;h很高的稳定性和支持热部|Ӏ模块扩展也很容易。当遇到讉K的峰|或者有人恶意发h速连接时Q也很可能会D服务器物理内存耗尽频繁交换Q失d应,只能重启服务器,Nginx采取了分阶段资源分配技术,处理静态文件和无缓存的反向代理加速,实现了负载均衡和定wQ在q样高ƈ发的讉K情况下,能经受v高ƈ发的处理?/p>

二.Nginx安装与配|?/strong>

  W一步:下蝲Nginx 安装?nbsp;

     http://nginx.org/en/download.html

  W二步:在linux上安装Nginx 

    1.#tar zxvf nginx-1.7.8.tar.gz  //解压

    2.#cd nginx-1.7.8

    3.#./configure --with-http_stub_status_module --with-http_ssl_module//启动server状态页和https模块

会报~少PCRE library错误Q如图所C:

Nginx 与Tomcat 实现动静态分R负载均?

q时先执行第三步安装PCRE Q然后在3执行一下,q就可以?/p>

   4.make && make install //~译q安?/p>

   5.试一下安装配|是否正?Nginx安装?usr/local/nginx

    #/usr/local/nginx/sbin/nginx -tQ如图所C:

    Nginx 与Tomcat 实现动静态分R负载均?


  W三步:在linux上安装PCRE 

    1.#tar zxvf pcre-8.10.tar.gz  //解压

    2.cd pcre-8.10

    3../configure

    4.make && make install//~译q安?/p>

三.Nginx +Tomcat 实现动静态分?/strong>

 

   动静态分d是Nginx处理客户端的h的静态页?html面)或者图片,Tomcat处理客户端请求的动态页面(jsp面Q,因ؓNginx处理的静态页面的效率高于Tomcat?/p>

  W一步:我们要配|Nginx文g

 #vi /usr/local/nginx/conf/nginx.conf

#user  nobody; worker_processes  1; error_log  logs/error.log; pid       logs/nginx.pid;  events {     use epoll;     worker_connections  1024; }   http {     include       mime.types;     default_type  application/octet-stream;     log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '                      '$status $body_bytes_sent "$http_referer" '                      '"$http_user_agent" "$http_x_forwarded_for"';      access_log  logs/access.log  main;     sendfile        on; keepalive_timeout  65; gzip on;   gzip_min_length  1k;   gzip_buffers     4  16k;   gzip_http_version 1.0;   gzip_comp_level 2;   gzip_types  text/plain application/x-javascript text/css application/xml;   gzip_vary on;       server {         listen       80 default;         server_name  localhost;         <span style="color:#ff0000;"> location ~ .*\.(html|htm|gif|jpg|jpeg|bmp|png|ico|txt|js|css)$ //由nginx处理静态页?lt;/span>              {                    root   /usr/tomcat/apache-tomcat-8081/webapps/ROOT;                     expires      30d; //~存到客L30?               }          error_page  404              /404.html;          #redirect server error pages to the static page /50x.html                  error_page   500 502 503 504  /50x.html;         location = /50x.html {             root   html;         }          <span style="color:#ff0000;"> location ~  \.(jsp|do)$  {//所有jsp的动态请求都交给Tomcat处理 </span>            <span style="color:#ff0000;"> proxy_pass http://192.168.74.129:8081;  //来自jsp或者do的后~的请求交ltomcat处理</span>             proxy_redirect off;             proxy_set_header Host $host;    //后端的Web服务器可以通过X-Forwarded-For获取用户真实IP             proxy_set_header X-Real-IP $remote_addr;             proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;             client_max_body_size 10m;   //允许客户端请求的最大单文g字节?            client_body_buffer_size 128k; //~冲Z理缓冲用Lh的最大字节数              proxy_connect_timeout 90;   //nginx跟后端服务器q接时旉              proxy_read_timeout 90;     //q接成功后,后端服务器响应时?             proxy_buffer_size 4k;      //讄代理服务器(nginxQ保存用户头信息的缓冲区大小              proxy_buffers  6  32k;       //proxy_buffers~冲区,|页q_?2k以下的话Q这栯|?            proxy_busy_buffers_size 64k;//高负荷下~冲大小Qproxy_buffers*2Q?           proxy_temp_file_write_size 64k; //讑֮~存文g夹大,大于q个|从upstream服务器传         }            }    }

 W二步:在tomcat 下的webapps/ROOT下新建index.html静态页面,如图所C:

Nginx 与Tomcat 实现动静态分R负载均? 

  W三步:启动Nginx服务

  #sbin/nginx   如图所C:

   Nginx 与Tomcat 实现动静态分R负载均?


 W四步:我们面讉Khttp://192.168.74.129/index.html 能正常显C正常的内容Q如图所C:

   Nginx 与Tomcat 实现动静态分R负载均?

  

 W五步:试Nginx 和Tomcat高ƈ发的情况下处理静态页面性能如何Q?/strong>

    采用?nbsp;Linux  ab|站压力试命o来测试一下性能

   1.试一下Nginx 处理静态页面的性能

     ab -c 100 -n 1000 http://192.168.74.129/index.html

     q个表示同时处理100个请求ƈq行1000ơindex.html文g,如图所C:

     Nginx 与Tomcat 实现动静态分R负载均?

   2.试一下Tomcat处理静态页面的性能

     ab -c 100 -n 1000 http://192.168.74.129:8081/index.html

     q个表示同时处理100个请求ƈq行1000ơindex.html文g,如图所C:

     Nginx 与Tomcat 实现动静态分R负载均?

   相同的处理静态文ӞNginx处理的静态性能比Tomcat 好。Nginx每秒能请?388ơ,而tomcat只请?609ơ?/p>


ȝQ我们在Nginx配置文g中,配置静态交lNginx处理Q动态请求交lTomcatQ提供了性能?/p>

 

四.Nginx +Tomcat 负蝲均衡与容?/strong>

  我们在高q发的情况下Qؓ了提高服务器的性能Q减了单台服务器的q发压力Q我们采用了集群部vQ还能解决ؓ了避免单台服务器挂掉Q服务不能访问这U情况下Q处理容错问题?/p>


 W一步:我们q边部v了两天tomcat服务器,192.168.74.129:8081?92.168.74.129:8082


 W二步:Nginx作ؓ了代理服务器Q客服端h服务器端Ӟ采用了负载均衡来处理Q这样就能^均的把客服端h分发到每一天服务器Q这样减服务器端的压力。配|Nginx下的nginx.conf文g?/strong>

   

  #vi /usr/local/nginx/conf/nginx.conf

    

#user  nobody; worker_processes  1; error_log  logs/error.log; pid       logs/nginx.pid;  events {     use epoll;     worker_connections  1024; }   http {     include       mime.types;     default_type  application/octet-stream;     log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '                      '$status $body_bytes_sent "$http_referer" '                      '"$http_user_agent" "$http_x_forwarded_for"';      access_log  logs/access.log  main;     sendfile        on; keepalive_timeout  65; gzip on;   gzip_min_length  1k;   gzip_buffers     4  16k;   gzip_http_version 1.0;   gzip_comp_level 2;   gzip_types  text/plain application/x-javascript text/css application/xml;   gzip_vary on;   <span style="color:#ff0000;">upstream localhost_server {         ip_hash;         server 192.168.74.129:8081;         server 192.168.74.129:8082;     }</span>      server {         listen       80 default;         server_name  localhost;        <span style="color:#ff0000;">  location ~ .*\.(html|htm|gif|jpg|jpeg|bmp|png|ico|txt|js|css)$ //由nginx处理静态页?lt;/span>              {                    root   /usr/tomcat/apache-tomcat-8081/webapps/ROOT;                     expires      30d; //~存到客L30?               }          error_page  404              /404.html;          #redirect server error pages to the static page /50x.html                  error_page   500 502 503 504  /50x.html;         location = /50x.html {             root   html;         }           <span style="color:#ff0000;">location ~  \.(jsp|do)$  {//所有jsp的动态请求都交给Tomcat处理 </span>            <span style="color:#ff0000;">proxy_pass http://localhost_server;  //来自jsp或者do的后~的请求交ltomcat处理</span>             proxy_redirect off;             proxy_set_header Host $host;    //后端的Web服务器可以通过X-Forwarded-For获取用户真实IP             proxy_set_header X-Real-IP $remote_addr;             proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;             client_max_body_size 10m;   //允许客户端请求的最大单文g字节?            client_body_buffer_size 128k; //~冲Z理缓冲用Lh的最大字节数              proxy_connect_timeout 90;   //nginx跟后端服务器q接时旉              proxy_read_timeout 90;     //q接成功后,后端服务器响应时?             proxy_buffer_size 4k;      //讄代理服务器(nginxQ保存用户头信息的缓冲区大小              proxy_buffers  6  32k;       //proxy_buffers~冲区,|页q_?2k以下的话Q这栯|?            proxy_busy_buffers_size 64k;//高负荷下~冲大小Qproxy_buffers*2Q?           proxy_temp_file_write_size 64k; //讑֮~存文g夹大,大于q个|从upstream服务器传         }            }    }


说明Q?/p>

   1.upstream 中的server是指向服务器的IPQ域名)和端口,后面q可以带参数

     1)weight Q设|服务器的{发权?nbsp;默认值是1?/p>

     2)max_fails Q?nbsp;是与fail_timeout配合使用Q是指在fail_timeout旉D内Q如果服务器转发p|ơ数过max_fails讄的|q台服务器就?                    可用Qmax_fails默认值是1

    3)fail_timeout :表示在该旉D内转发p|多少ơ就认ؓq台服务器不能用?/p>

    4)downQ表C台服务器不能用?/p>

     5)backupQ表CZip_hash讄的针对这台服务器无效Q只有在所有非备䆾的服务器都失效后Q才会向服务器{发请求?/p>

 

  2.ip_hash 讄是在集群的服务器中,如果同一个客Lh转发到多个服务器上,每台服务器可能缓存同一份信息,q会造成资源的浪费,采用的ip_hash讄会把同一个客LW二ơ请求相同的信息Ӟ会{发到W一ơ请求的服务器端。但ip_hash不能和weight 同时使用?/p>



fly 2015-02-01 23:18 发表评论
]]> վ֩ģ壺 ؼƬѸƵ| ִֻˬƬ | ˾þô߽| óۺ| ߹ۿƵ| ˬִֻ̼վ | ŮƵ77777 | ާѡþþþƷ9966| ޹һ| 51ƵƷȫ| þþƷձҰ| 3pһ| Ѹ弤Ƶ| ŮƵ| xxxxxƬƵ| ij4438| aƬ߲| avרۿƷ| ɫžžȫƵ| ǴýƵѹۿ| ޸ߵӰ| һɫëƬ| 67194츾ѹۿ| þ޾Ʒϵַ| Ʒ޲Ʒһ| ƷƵ| ҹӰһ| þþþƷ޳18վ | Ļ| С˵ͼƬ| 㶮߹ۿվ| þþþ޹AV鶹| ޹ɫƵ| Ʒ߳| ҹҹƵ| ޾ƷƵ| 97߹ۿƵ| ŮƷþþþ| þþþþaŷa| Ѵѧ߹ۿp| ƷһVR|