??xml version="1.0" encoding="utf-8" standalone="yes"?>99亚洲精品高清一二区,丁香婷婷亚洲六月综合色,亚洲av中文无码乱人伦在线观看 http://m.tkk7.com/inter12/zh-cnMon, 12 May 2025 10:39:59 GMTMon, 12 May 2025 10:39:59 GMT60个h博客q移http://m.tkk7.com/inter12/archive/2015/03/22/423722.html薛n?/dc:creator>薛n?/author>Sun, 22 Mar 2015 08:27:00 GMThttp://m.tkk7.com/inter12/archive/2015/03/22/423722.htmlhttp://m.tkk7.com/inter12/comments/423722.htmlhttp://m.tkk7.com/inter12/archive/2015/03/22/423722.html#Feedback0http://m.tkk7.com/inter12/comments/commentRss/423722.htmlhttp://m.tkk7.com/inter12/services/trackbacks/423722.html说明blogjava在google引擎中的排名实非常高,不过q个博客中一些文章资料也实很好Q是个h见过最好的?br />不过自己已经博客地址q移到自己新的个人地址上了Q?inter12.org 

]]>
一ơ线上jboss僉|问题分析http://m.tkk7.com/inter12/archive/2012/09/17/387938.html薛n?/dc:creator>薛n?/author>Mon, 17 Sep 2012 13:09:00 GMThttp://m.tkk7.com/inter12/archive/2012/09/17/387938.htmlhttp://m.tkk7.com/inter12/comments/387938.htmlhttp://m.tkk7.com/inter12/archive/2012/09/17/387938.html#Feedback0http://m.tkk7.com/inter12/comments/commentRss/387938.htmlhttp://m.tkk7.com/inter12/services/trackbacks/387938.html问题再现Q?/div>
  个h中心在上周四上线(2012.9.13)W一ơ上U,׃U种~由Q遗留了部分低别的BUGQ后于次日修复,下午4时再ơ上Uѝ?/div>
  当日晚上8点,q维发现user-web 五台服务器中四台jboss僉|Q无法响应用戯求?/div>
问题分析Q?/div>
  问题发生当日Q运l截留了当时的日志信息ƈdump 了JVM内存信息Q关键信息如下:
  
  java.lang.NullPointerException
Message 2012-09-15 02:47:56,992 - com.dianping.userweb.service.processor.MyInfoFavouriteModuleProcessor -235970 [myInfoThreadPoolTaskExecutor-1] ERROR - com.dianping.userweb.service.processor.MyInfoFavouriteModuleProcessor process module exception.
  ......
   
  "http-0.0.0.0-8080-271" daemon prio=10 tid=0x00002b6ef4211000 nid=0x292a waiting on condition [0x00002b6eac592000]
   java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x00000007c4a3f0f0> (a java.util.concurrent.CountDownLatch$Sync)
        at java.util.concurrent.locks.LockSupport.park(LockSupport.java:158)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:811)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedInterruptibly(AbstractQueuedSynchronizer.java:969)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(AbstractQueuedSynchronizer.java:1281)
        at java.util.concurrent.CountDownLatch.await(CountDownLatch.java:207)
        at com.dianping.userweb.framework.concurrent.ConcurrentSidebarManager.execute(ConcurrentSidebarManager.java:46)
        at com.dianping.userweb.action.page.myinfo.MyInfoIndexAction.sideBarManagerExecute(MyInfoIndexAction.java:39)
        
   ......
   
   从以上日志中我们可以得到两个信息
   1.一?process报了I指针异常,
   2.一个线E一直处在waiting状态?/div>
   
   Ҏ日志扑ֈ对应的代码:
   
   
     @Override
    public void execute(final UCActionContext context) throws ProjectException {
        final CountDownLatch countDownLatch = new CountDownLatch(getHeadSize() + getLeftSize() + getRightSize());
        barHandleExecute(context, countDownLatch, sideBar);
        try {
            countDownLatch.await();                            --- A 
        } catch (InterruptedException e) {
            logger.error("current handle error!", e);
            throw new ProjectException("current handle error!");
        }
    }
    
    q段是处理ƈ行的核心代码Q通过CountDownLatch来处理ƈ行的执行Q主U程通过 countDownLatch.await();{待子线E的完成。这个方法会抛除InterruptedException异常Q这个异常包含三个含义:
    
    1.q是一个异常,需要业务根据时间情况处理,当然有些废话
    2.q是一个等待方法,{待的时间不ҎCPU或是内存的情况,而是依赖于定时器或是盘IO的返回,本案是根据子U程的执行情?/div>
    3.q个{待U程是可以中断的
    所以当一个请求过来时Q主U程会在q个A处等待,直到所有子U程告诉我,所有子U程已经执行完成了?/div>
    
    再看barHandleExecuteҎ的处理:
    
     protected void barHandleExecute(final UCActionContext context, final CountDownLatch countDownLatch, SideBar sideBar) {
       
       ....... 
                threadPoolTaskExecutor.execute(new Runnable() {
                    @Override
                    public void run() {
                        Transaction t = Cat.getProducer().newTransaction("Modules",
                                                                         moduleProcessor.getClass().getName());// 接入cat
                        try {
                            moduleProcessor.execute(context);
                            countDownLatch.countDown();
                            t.setStatus(Transaction.SUCCESS);
                        } catch (Throwable e) {
                            Cat.getProducer().logError(e);// 用log4j记录pȝ异常Q以便在Logview中看到此信息
                            t.setStatus(e);
                            
                        } finally {
                            t.complete();  
                        }
                    }
                });
      .......
    }
    
    对于多个U程Q通过U程池来处理Q每个线E也是moduleProcessor处理完成后, countDownLatch.countDown();告诉ȝE我已经执行完成了,当主U程收到所有子U程的答复后Ql往下执行,q行面的渲染?/div>
    
    以上都是正常程的流转过E,但是Q若我们其中的一个moduleProcessor抛出异常后,会出C么情况呢Q这个异怼被接入CAT监控的代码会吃掉Q告诉CAT一个日志信息,然后׃么都不做了。那countDownLatch.countDown();q段代码永q不会被执行Q而主U程又依赖于子线E通过countDownLatch.countDown();来告知是否执行完了。这个时候就悲剧了,ȝE一直在{待子线E的消息Q无法渲染页面返回结果,q个时候用LW一反应会是是不是网l原因导致没有加载数据,不停的F5Q每ơ都会生一个新的请求进来,若是h的h多Q这些进E就永远僉|在那边,不释攑ֆ存,造成pȝ雪崩?/div>
    
    一个合理的介入CAT方式是:
      Transaction t = Cat.getProducer().newTransaction("Modules",
                                                                         moduleProcessor.getClass().getName());// 接入cat
                        try {
                            // 业务处理
                            t.setStatus(Transaction.SUCCESS);
                        } catch (Throwable e) {
                            Cat.getProducer().logError(e); 
                            t.setStatus(e);
                            throw new ProjectException();  //q里必须抛出异常Q有业务pȝ军_如何处理异常
                        } finally {
                            t.complete();  
                        }
    
几个疑问Q?/div>
1.Z么processor会抛出异常?
当时在porcessor~写的时候,U定各个processor需要cacth自己的异常,不能因ؓ自己的失败导致请求的其他模块加蝲p|。我们看看报I指针的地方Q?/div>
.....
context.getParam(DefaultActionContext.Contant.MEMBER_ID.name)
.....
try
...
报错的是从上下文获取memberID的代码,q个操作q没有放在try catch块中。由于个Z心的所有页面都必须依赖于memberIDq个字段Q所以编码时忽略了memberId为空的这U情况,而且在我们的action层也对memberID为空的情况作了处理,具体代码如下Q?/div>
......
private void initMemberInfo(UCActionContext context) throws ProjectException {
        // 验证会员存在
        if (memberId == null) {
            throwException(MemberUtil.MEMBERID_INVALID_TITLE, MemberUtil.MEMBERID_INVALID_MSG);
        }
...... 
所以理Z来说Q对于memberId为空的情况不会进入后端处理的processorQ所以后端也没有考虑Ccontext获取memberID会ؓI,但是实际情况q是发生了,q段代码也做了拦截,q抛Z异常Q不q?在initMemberInfoq个Ҏ的外层,又catch住了q个异常Q?/div>
try
  ....
   initMemberInfo(context);
   
catch(){
  ....
}
所以说ACTION做的处理q没有v到拦截作用,Dq个null的memberid传递到了后端,后端出错后被接入CAT的代码抓住,DȝE一直得不到q回?/div>
2.Z么在压力试q程中没有发生这个问题?
压力试q程Ӟ当时扚w处理ҎbarHandleExecute的源代码如下所C,q没有介入CAT监控代码
 protected void barHandleExecute(final UCActionContext context, final CountDownLatch countDownLatch, SideBar sideBar) {
       
       ....... 
                threadPoolTaskExecutor.execute(new Runnable() {
                    @Override
                    public void run() {
                     
                            moduleProcessor.execute(context);
                            countDownLatch.countDown();
                    }
                });
      .......
    }
q个地方Z么没有做try catchQ是考虑到我们一些ƈ行的processor存在一些依赖关p,processorA出异常的话,processorBq不出问题Q也不渲染页面。所以这里就不cacth异常Q由具体的processor来决定是否cacth异常。所以在压力试q程Q就其中processor抛出异常Q框架就认ؓq是某个依赖processor抛出的异常,将q个异常抛到WEBQ由最外层做控Ӟ跌{到统一的错误页面。所以这ȝE僵ȝ情况׃会出现?/div>
3.周四上线的时候ؓ什么没有让jboss僉|Q?/div>
个h中心周四晚上9点多上线Q当时访问量也不是很大,q到会导致一些无效的memberID的请求进入,也不会立刻让JBOSS僉|。同时我们在周五下午又对个h中心做了一ơ上U,重启了应用了Q所以没报出q个问题Q但是在周五晚上Q请求增大,各种复杂情况的请求进入后Q就触发了我们代码中的缺P最l导致JBOSS僉|?/div>
ȝQ?/div>
1.前段action拦截不合理,攑օ了memberId为NULL的请求,打开了系l出错的门?/div>
2.后端processor信Q前段q来的数据,q没有做防M式处理,DI指针异常,同时又没有将q段获取数据的代码纳入try中,q一步将pȝ推向奔溃边缘?/div>
3.上线前接入CAT代码Q没有考虑全面Q这D代码在自己本分(记录pȝ执行开销及异?外干了不是它的事Qcacth住了我们的系l异常,q个才是压垮pȝ的最后一根稻草,Dpȝ雪崩?/div>
4.框架本n考虑不够全面Q用一U靠扩展对自w的U束来处理异常情况,没有分开的去处理Q多个无关porcessor和多个存在关联processor的两U情c?/div>
以上四步Q只要不走错一步,׃会出现周五晚上的JBOSS僉|问题。可见一个重大错误大多是׃pd的错误连锁导致的?/div>
    
    
   
   
   
  


]]>一ơ性能调优W记(U程?http://m.tkk7.com/inter12/archive/2012/09/12/387837.html薛n?/dc:creator>薛n?/author>Wed, 12 Sep 2012 13:17:00 GMThttp://m.tkk7.com/inter12/archive/2012/09/12/387837.htmlhttp://m.tkk7.com/inter12/comments/387837.htmlhttp://m.tkk7.com/inter12/archive/2012/09/12/387837.html#Feedback0http://m.tkk7.com/inter12/comments/commentRss/387837.htmlhttp://m.tkk7.com/inter12/services/trackbacks/387837.html普通的性能调优主要从四个方面入?/p>

|络Q磁盘IOQ内存,CPU四个斚w入手Q下面案例就是从q四个角度来看?/p>

 

我们的页面每天PV?0W Q主要是分布在两个主要页面:个h主页Q展CZc假设每个页面各自承?0%的PVQ假设访问时间集中在白天8时Q^均下来每U的h数是 5.2个,考虑到高峰情况,那么我们׃以系?0, 当100个处理,我们最大的一个请求会产生13个processor ,也就是说 最大生的U程回事 13*100 = 1300。也是说高峰时M?300个线E需要被处理Q我们将队列讄?000Q对于高峰情况就抛弃Q因是ؓ了满高峰情늚需要,׃使得部分h处在队列中,不能充分的利用CPU的资源?/p>

 

在做压力试时候,自n应用内部做了的多线E处理的框架Q内部采用的U程池是 SPRING?ThreadPoolTaskExecutor 的类Q通过自n的一个监控框架我们发玎ͼ所有的U程单元执行的很快,但是在最后组装processor的时候,p了时_在过E中观察CPU的利用率q不是很高?/p>

所以预估是在等待所有线E执行完成时Q也是说有大量的processor在线E池的等待队列中Qؓ了验证是否由于该原因造成的,所以做如下试Q?/p>

 

因ؓ前面提到每秒的^均请求是5.2 考虑C般的情况Q就讄为压的q发Cؓ 3*5 = 15.

 

试案例一Q?/span>

 

15U程 

循环100?/p>

U程池:

 corePoolSize Q?CPU = 4 

 maxPoolSize  Q?2 * corePoolSize = 8 

 queueCapacity Q?1000 

 

压测面Q?/xxx/22933 

 

---------------------------------------------- q个是分割线 ----------------------------------------------

E_情况下的U程敎ͼ

[root@host_77-69 ~]# ps -eLf | grep java  | wc -l 

229

主要是观察,是否充分利用了CPU核数Q达到我们预期的效果。现在的服务l承很多框架或是模块后,会启动很多你不知道的U程Q在那跑着Q时不时跛_来干C下,所以一定要{系l运行稳定后观察q个数倹{?/p>

---------------------------------------------- q个是分割线 ----------------------------------------------

CPU的一些信息:

[root@host_77-69 ~]# vmstat -ns 3  
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 0  0   2056 723528 392024 1330728    0    0     0     1    1    2  0  0 100  0  0	
 0  0   2056 723404 392024 1330728    0    0     0     0  467  806  0  0 100  0  0	
 0  0   2056 723404 392028 1330728    0    0     0    17  462  807  0  0 100  0  0	
 0  0   2056 723404 392028 1330728    0    0     0     0  457  814  0  0 100  0  0
  

主要是关?in Q?cs q两个参?/p>

inQ每UY中断ơ数

cs: 每秒上下文切换的ơ数

 

因ؓ操作pȝ本n会有一些操作,在未压测前的数值基本在 460 .800 左右?/p>

---------------------------------------------- q个是分割线 ----------------------------------------------

 

[root@host_77-69 ~]#  mpstat -P ALL 5 
Linux 2.6.32-71.el6.x86_64 (host_77-69) 	09/12/2012 	_x86_64_	(4 CPU)

02:04:21 PM  CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest   %idle
02:04:26 PM  all    0.10    0.00    0.00    0.00    0.00    0.00    0.00    0.00   99.90
02:04:26 PM    0    0.20    0.00    0.00    0.00    0.00    0.00    0.00    0.00   99.80
  

xsoft q个参数 q个代表当前CPU在所有时间中Q用于切换上下所化时间比,若是p的越多,代表当前的线E切换过于频J,没有充分利用CPUQ徏议减线E数或是增加CPU?/p>

user ?nice、sys主要是观察系l中是否存在大量计算Q或是死循环的情况,来消耗大量的CPU?/p>

q个命o是对于vmstat的补充,更直观的观察CPU的上下文切换及Y中断情况?/p>

 

---------------------------------------------- 下面是内存的初始情况?----------------------------------------------

JVM自n的内存情况:

 

[root@host_77-69 ~]# jstat -gcutil `jps | grep -i main | awk '{print $1}'` 3000 1000 
  S0     S1     E      O      P     YGC     YGCT    FGC    FGCT     GCT   
  0.00   0.00  90.91  13.56  60.25     26    0.877     2    0.802    1.679
  0.00   0.00  91.17  13.56  60.25     26    0.877     2    0.802    1.679
  0.00   0.00  91.27  13.56  60.25     26    0.877     2    0.802    1.679
  0.00   0.00  91.28  13.56  60.25     26    0.877     2    0.802    1.679
 

fugccơ数基本不变Q而且各个代内存变化基本不大?/p>

 

操作pȝ的内存情况:

 

[root@host_77-69 releases]# for i in {1..10};do  free;sleep 3  ; done;
             total       used       free     shared    buffers     cached
Mem:       3925596    3223996     701600          0     392352    1330896
-/+ buffers/cache:    1500748    2424848
Swap:      4194296       2056    4192240
             total       used       free     shared    buffers     cached
Mem:       3925596    3223996     701600          0     392352    1330896
-/+ buffers/cache:    1500748    2424848
Swap:      4194296       2056    4192240
             total       used       free     shared    buffers     cached
Mem:       3925596    3223996     701600          0     392352    1330896
-/+ buffers/cache:    1500748    2424848
Swap:      4194296       2056    4192240
  

数g基本保持不变?/p>

 

---------------------------------------------- 下面是磁盘IO的初始情况了 ---------------------------------------------- 

 

[root@host_77-69 ~]# for i in {1..10};do  iostat ; sleep 3 ; done ;
Linux 2.6.32-71.el6.x86_64 (host_77-69) 	09/12/2012 	_x86_64_	(4 CPU)

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           0.10    0.00    0.02    0.00    0.00   99.88

Device:            tps   Blk_read/s   Blk_wrtn/s   Blk_read   Blk_wrtn
sda               0.31         0.33         5.93    1751462   31740872

Linux 2.6.32-71.el6.x86_64 (host_77-69) 	09/12/2012 	_x86_64_	(4 CPU)

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           0.10    0.00    0.02    0.00    0.00   99.88

Device:            tps   Blk_read/s   Blk_wrtn/s   Blk_read   Blk_wrtn
sda               0.31         0.33         5.93    1751462   31740960
  

主要观察 

Blk_read/s    每秒中读取的块数

Blk_wrtn/s    每秒中写的块?/p>

%iowait       当前在等待磁盘IO的情?/p>

 

---------------------------------------------- 说了q么多终于要开始了 ---------------------------------------------- 

 

开始压后Q得C面的数据Q?/p>

 

[root@host_77-69 ~]# vmstat -ns 3  
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu-----
0  0   2056 698224 393212 1331344    0    0     0     3  536  867  0  0 100  0  0	
 3  0   2056 694796 393212 1332248    0    0     0    19 7170 7515 55  4 40  0  0	
 1  0   2056 694796 393212 1333132    0    0     0     4 7121 7627 50  5 45  0  0	
 4  0   2056 692936 393216 1334376    0    0     0    17 6478 8738 54  5 42  0  0	
 2  0   2056 691548 393232 1335620    0    0     0    25 6497 7663 48  4 48  0  0	
 5  0   2056 689936 393232 1337052    0    0     0     3 7597 7174 47  5 48  0  0	
 3  0   2056 688704 393232 1338496    0    0     0    12 7369 8774 49  5 45  0  0	
 3  0   2056 686348 393232 1341528    0    0     0   819 12298 16011 50  5 45  0  0	
 4  0   2056 684976 393236 1343020    0    0     0    12 6034 6951 48  4 48  0  0	
 3  0   2056 664268 393240 1344508    0    0     0     1 6731 9584 52  5 42  0  0	
 1  0   2056 659360 393240 1346284    0    0     0    12 7797 8431 54  5 41  0  0	
 2  0   2056 657624 393240 1347564    0    0     0  2684 6908 7656 50  5 45  0  0	
  

在压的q个q程中,CPU大量上下文切换动作明昑֢加了很多?/p>

 

[root@host_77-69 ~]#  mpstat -P ALL 5 
 04:01:32 PM  CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest   %idle
04:01:37 PM  all    0.15    0.00    0.10    0.00    0.00    0.05    0.00    0.00   99.70
04:01:37 PM    0    0.20    0.00    0.00    0.00    0.00    0.20    0.00    0.00   99.60
04:01:37 PM    1    0.20    0.00    0.00    0.00    0.00    0.00    0.00    0.00   99.80
04:01:37 PM    2    0.20    0.00    0.00    0.00    0.00    0.00    0.00    0.00   99.80
04:01:37 PM    3    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00  100.00
 

q个数据上看出其中一个CPUp在切换的旉比是0.2%Q也不是很高?/p>

 

 [root@host_77-69 ~]# ps -eLf | grep java  | wc -l 
229
[root@host_77-69 ~]# ps -eLf | grep java  | wc -l 
236
[root@host_77-69 ~]# ps -eLf | grep java  | wc -l 
236
[root@host_77-69 ~]# ps -eLf | grep java  | wc -l 
235
[root@host_77-69 ~]# ps -eLf | grep java  | wc -l 
229
[root@host_77-69 ~]# ps -eLf | grep java  | wc -l 
229
  

java的线E数增加C236Q也是说增加了7个,我们最初设|是4个,队列1000 Q在队列满了后,增加?个,也就是说Q这U情况,扩容?个线E,p满我们的压条Ӟ那说明core?Q存在大量的队列U压情况Q同Ӟ上面的数据表明,用于上下文切换的比例也不是很高,如此我们可以增加线E池的corePoolSize。那么下个案例就可以讄?个试试看?/p>

 

[root@host_77-69 ~]# jstat -gcutil `jps | grep -i main | awk '{print $1}'` 3000 1000 
  S0     S1     E      O      P     YGC     YGCT    FGC    FGCT     GCT   
 0.00  27.46  76.94  19.37  60.86     31    1.139     3    1.497    2.636
  0.00  23.34  85.64  19.37  60.90     33    1.150     3    1.497    2.647
  0.00  36.14  38.44  19.37  60.91     35    1.167     3    1.497    2.665
  0.00  63.19  37.87  19.37  60.92     37    1.191     3    1.497    2.688
 59.29   0.00   1.61  19.48  60.92     40    1.226     3    1.497    2.723
  0.00  50.63  58.22  19.50  60.93     41    1.236     3    1.497    2.733
  0.00  51.09  70.36  19.58  60.94     43    1.265     3    1.497    2.762
 44.05   0.00   2.09  19.67  60.95     46    1.298     3    1.497    2.795
  0.00  83.74  75.70  19.68  60.96     47    1.316     3    1.497    2.813
  0.00  89.57  77.32  20.21  60.96     49    1.350     3    1.497    2.847
 46.02   0.00  36.83  22.12  60.97     52    1.399     3    1.497    2.896
 36.69   0.00  37.78  22.12  60.98     54    1.417     3    1.497    2.914
 59.51   0.00  23.47  22.12  61.00     56    1.435     3    1.497    2.932
 64.53   0.00  36.51  22.29  61.03     58    1.461     3    1.497    2.959
 73.19   0.00  78.00  23.01  61.05     60    1.497     3    1.497    2.995
 54.24   0.00  36.10  23.01  61.06     62    1.521     3    1.497    3.018
 79.36   0.00  82.65  23.01  61.08     64    1.547     3    1.497    3.044
  0.00  68.75  48.34  26.61  61.10     67    1.606     3    1.497    3.103
 29.33   0.00  93.75  26.61  61.12     68    1.613     3    1.497    3.110
  0.00  45.32  23.68  26.61  61.12     71    1.640     3    1.497    3.138
 34.93   0.00  19.75  29.84  61.13     74    1.697     3    1.497    3.194
 22.59   0.00  27.47  29.84  61.14     76    1.711     3    1.497    3.208
 54.40   0.00  74.16  30.45  61.15     78    1.734     3    1.497    3.231
 25.23   0.00  77.50  30.45  61.15     80    1.747     3    1.497    3.245
 25.23   0.00  98.39  30.45  61.15     80    1.747     3    1.497    3.245
 25.23   0.00  99.94  30.45  61.15     80    1.747     3    1.497    3.245
  0.00  14.32   1.42  30.45  61.15     81    1.752     3    1.497    3.250
  0.00  14.32   2.15  30.45  61.15     81    1.752     3    1.497    3.250
  0.00  14.32   2.27  30.45  61.15     81    1.752     3    1.497    3.250
  0.00  14.32   2.48  30.45  61.15     81    1.752     3    1.497    3.250

 

 

q个是查看JVM的GC情况的,数据表明Q压期_ygcq是蛮频J,但是每次ygc后进入old区的数据q不是很多,说明我们的应用大部分是朝生夕死,q不会发生频Jfgc的情况,之后׃用把重心攑֜JVM的GC上?/p>

 

[root@host_77-69 releases]# for i in {1..10};do  free;sleep 3  ; done;
             total       used       free     shared    buffers     cached
Mem:       3925596    3370968     554628          0     395584    1369572
-/+ buffers/cache:    1605812    2319784
Swap:      4194296       2056    4192240
 

操作pȝ跟之心前相比Q基本没有发生Q何的改变?/p>

 

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           0.10    0.00    0.02    0.00    0.00   99.88

Device:            tps   Blk_read/s   Blk_wrtn/s   Blk_read   Blk_wrtn
sda               0.31         0.33         5.95    1751462   31823032

Linux 2.6.32-71.el6.x86_64 (host_77-69) 	09/12/2012 	_x86_64_	(4 CPU)

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           0.10    0.00    0.02    0.00    0.00   99.88

Device:            tps   Blk_read/s   Blk_wrtn/s   Blk_read   Blk_wrtn
sda               0.31         0.33         5.95    1751462   31823032

 

 

q个是当前应用对于磁盘的消耗情况,Ҏ初始|基本没什么变化,可以看出我们q个应用没有盘IO的消耗,q说明本应用q没有大量的操作本地盘IO情况?/p>

q个也不是导致我们系l慢的原因,也可以排除?/p>

 

 

xxxModuleProcessor 33 最慢的processor?3毫秒

 

我们的processor最大的消耗是33毫秒Q外部调?.9ms Q但是最后看到的消耗时间是557msQ且上面的情况说明了Q存在大量队列积压,我们的数据处理processor都在{待队列?/p>

 

下面是我们通过

Avg(ms):

W一ơ: 662.5 毫秒

W二ơ: 680   毫秒

W三ơ: 690   毫秒

 

通过上面的分析,q_响应旉是:680ms,基本可以定问题在于U程池corePoolSizeq小,D了一定的数据在队列中U压?/p>

 

 

---------------------------------------------  q是一条伟大的分割U? ---------------------------------------------

试案例二:

 

改动Q增加一倍的corePoolSize

 

15U程 

循环100?/p>

U程池:

 corePoolSize Q? * CPU =  8 

 maxPoolSize  Q? * corePoolSize = 16 

 queueCapacity Q?1000 

 

压测面Q?/member/22933 

 

---------------------------------------------  我又出现? ---------------------------------------------

 

再次启动E_后:

[root@host_77-69 ~]# for i in {1..10000};do    ps -eLf | grep java  | wc -l; echo "-------" ; sleep 2 ; done;

215

-------

215

-------

215

-------

 

java的线E数l持?15个,跟上面有点不同,当然不管了,q个不是重点?/p>

 

 

[root@host_77-69 ~]# vmstat -ns 3  
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu-----
 0  0   2056 933420 395768 1341376    0    0     0     8  579  875  0  0 100  0  0	
 0  0   2056 933420 395768 1341376    0    0     0     3  579  860  0  0 100  0  0	
 0  0   2056 933420 395776 1341372    0    0     0     9  568  867  0  0 100  0  0	
 

 

初始情况CPUq行都很正常 

 

 

[root@host_77-69 ~]#  mpstat -P ALL 5 
Linux 2.6.32-71.el6.x86_64 (host_77-69) 	09/12/2012 	_x86_64_	(4 CPU)

05:43:34 PM  CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest   %idle
05:43:39 PM  all    0.40    0.00    0.10    0.00    0.00    0.00    0.00    0.00   99.50
05:43:39 PM    0    0.80    0.00    0.20    0.00    0.00    0.00    0.00    0.00   99.00

 

基本没有软中?/p>

 

压测后得到如下数据:

[root@host_77-69 ~]# for i in {1..10000};do    ps -eLf | grep java  | wc -l; echo "-------" ; sleep 2 ; done;

214

-------

214

-------

214

-------

217

-------

219

-------

219

-------

。。。。。?/p>

221

-------

219

-------

。。。。。?/p>

218

-------

218

-------

214

-------

q个javaU程数的变化情况Q从 214-- 221 -- 214?初始化了8个,然后增加?个,也就是说U程池中d启用?5个线E?/p>

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

 

[root@host_77-69 ~]#  mpstat -P ALL 5 
05:59:00 PM  CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest   %idle
05:59:05 PM  all   51.46    0.00    4.58    0.00    0.29    2.00    0.00    0.00   41.67
05:59:05 PM    0   50.98    0.00    4.71    0.00    0.98    7.25    0.00    0.00   36.08
05:59:05 PM    1   51.07    0.00    4.29    0.00    0.00    0.39    0.00    0.00   44.25
05:59:05 PM    2   50.49    0.00    4.87    0.00    0.00    0.19    0.00    0.00   44.44
05:59:05 PM    3   53.29    0.00    4.46    0.00    0.00    0.19    0.00    0.00   42.05

05:59:05 PM  CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest   %idle
05:59:10 PM  all   49.56    0.00    4.25    0.00    0.29    2.00    0.00    0.00   43.89
05:59:10 PM    0   46.56    0.00    3.73    0.00    1.18    7.07    0.00    0.00   41.45
05:59:10 PM    1   58.12    0.00    4.31    0.00    0.00    0.39    0.00    0.00   37.18
05:59:10 PM    2   45.72    0.00    4.67    0.00    0.00    0.39    0.00    0.00   49.22
05:59:10 PM    3   47.95    0.00    4.29    0.00    0.00    0.39    0.00    0.00   47.37

05:59:10 PM  CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest   %idle
05:59:15 PM  all   50.54    0.00    4.19    0.00    0.29    1.75    0.00    0.00   43.23
05:59:15 PM    0   55.36    0.00    3.70    0.00    1.17    5.85    0.00    0.00   33.92
05:59:15 PM    1   53.62    0.00    4.70    0.00    0.00    0.59    0.00    0.00   41.10
05:59:15 PM    2   46.98    0.00    4.29    0.00    0.00    0.19    0.00    0.00   48.54
05:59:15 PM    3   46.21    0.00    4.27    0.00    0.00    0.19    0.00    0.00   49.32

05:59:15 PM  CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest   %idle
05:59:20 PM  all   52.78    0.00    4.48    0.05    0.39    2.14    0.00    0.00   40.17
05:59:20 PM    0   52.17    0.00    3.94    0.00    1.57    7.68    0.00    0.00   34.65
05:59:20 PM    1   52.35    0.00    4.90    0.00    0.00    0.39    0.00    0.00   42.35
05:59:20 PM    2   57.09    0.00    4.85    0.00    0.00    0.19    0.00    0.00   37.86
05:59:20 PM    3   49.42    0.00    4.23    0.00    0.00    0.38    0.00    0.00   45.96

05:59:20 PM  CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest   %idle
05:59:25 PM  all   46.90    0.00    3.85    0.00    0.34    1.76    0.00    0.00   47.15
05:59:25 PM    0   48.34    0.00    3.70    0.00    1.56    6.43    0.00    0.00   39.96
05:59:25 PM    1   43.30    0.00    4.47    0.00    0.00    0.39    0.00    0.00   51.84
05:59:25 PM    2   50.59    0.00    3.52    0.00    0.00    0.39    0.00    0.00   45.51
05:59:25 PM    3   45.14    0.00    3.70    0.00    0.00    0.19    0.00    0.00   50.97
  

上面的数据表明,中断占CPU的比例确大大增加了。单怸断最高达C7.25% 如此D了什么结果呢?

 

Min(ms) Max(ms) Avg(ms) 95Line(ms) Std(ms) TPS

161.2  8877.4 731.7  1000.0    65.3  1.2

 

x较corePoolSize:4 max:8 性能反而下降了。^均响应时间从662.5降到?31.7?/p>

 

最慢的processor的消耗时间是Q?span style="white-space: pre;"> 187.9

 

期间也猜可能是其中一个服务被我们压坏了,重启了那个服务Q再ơ压的l果?/p>

Min(ms) Max(ms) Avg(ms) 95Line(ms) Std(ms) TPS

102.9  9188.9 762.5  1095.0    657.8  3.0

 

q_响应旉是:750毫秒左右?/p>

 

也就是说Q基本可以确认是׃我们增加?coreSize和maxSizeD性能变慢了。慢了近80毫秒。说明过多的CPUq不会加快我们的处理速度?/span>

如此有了下面的Ҏ?/p>

 

试Ҏ三:

corePoolSize : cpu数量 + 1  = 5 

maxPoolSzie : 2 * corePoolSize  = 10 

 

我们看下具体情况吧:

 

 

[root@host_77-69 ~]#  mpstat -P ALL 5 
06:57:36 PM  CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest   %idle
06:57:41 PM  all   58.27    0.00    5.38    0.00    0.49    2.30    0.00    0.00   33.56
06:57:41 PM    0   61.66    0.00    4.74    0.00    1.98    8.10    0.00    0.00   23.52
06:57:41 PM    1   55.75    0.00    5.65    0.00    0.00    0.58    0.00    0.00   38.01
06:57:41 PM    2   57.81    0.00    5.47    0.00    0.00    0.20    0.00    0.00   36.52
  

CPU的上下文切换q是很厉実뀂达C8.10%

[root@host_77-69 ~]# for i in {1..10000};do    ps -eLf | grep java  | wc -l; echo "-------" ; sleep 2 ; done;

214

-------

214

-------

219

-------

219

-------

217

-------

215

-------

214

 

214--219 

原来U程池core?Q我们最大是10个,U程数确实增加到?0个,是?0个线E对应到4个CPU上,两者的比例?:2.25 

 

l果Q?/p>

W一ơ压是Q?48毫秒

W二ơ压是Q?22毫秒

W三ơ压是Q?03毫秒

 

取中间值吧Q?22毫秒 

 

性能x?coreQ? max:16的话Q有0.060毫秒的提升。说明一定cpu和进E数保持?:2.25的比例上Q效率上q是有提高的Q但是上下文切换的还是很厉害?/span>

 

Z不让它切换的q么厉害Q就max讄的小点吧?/p>

 

试Ҏ?/span>

U程Q?5 

循环Q?00?/p>

corePoolSize : cpu数量 + 1    =  5 

maxPoolSzie : 2 * cpu    =  8

 

08:13:13 PM  CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest   %idle
08:13:18 PM  all   52.45    0.00    4.60    0.00    0.10    1.27    0.00    0.00   41.58
08:13:18 PM    0   60.00    0.00    3.96    0.00    0.59    3.96    0.00    0.00   31.49
08:13:18 PM    1   50.29    0.00    5.48    0.00    0.00    0.20    0.00    0.00   44.03
08:13:18 PM    2   50.78    0.00    4.86    0.00    0.00    0.58    0.00    0.00   43.77
08:13:18 PM    3   48.83    0.00    4.28    0.00    0.00    0.19    0.00    0.00   46.69

08:13:18 PM  CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest   %idle
08:13:23 PM  all   50.05    0.00    4.29    0.00    0.10    1.22    0.00    0.00   44.34
08:13:23 PM    0   57.54    0.00    4.56    0.00    0.20    3.97    0.00    0.00   33.73
08:13:23 PM    1   49.81    0.00    4.28    0.00    0.00    0.39    0.00    0.00   45.53
08:13:23 PM    2   48.16    0.00    3.88    0.00    0.00    0.39    0.00    0.00   47.57
08:13:23 PM    3   45.07    0.00    4.45    0.00    0.00    0.19    0.00    0.00   50.29

08:13:23 PM  CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest   %idle
08:13:28 PM  all   51.34    0.00    4.69    0.00    0.10    1.27    0.00    0.00   42.60
08:13:28 PM    0   60.08    0.00    4.15    0.00    0.40    3.95    0.00    0.00   31.42
08:13:28 PM    1   47.75    0.00    6.07    0.00    0.00    0.39    0.00    0.00   45.79
08:13:28 PM    2   47.48    0.00    4.26    0.00    0.00    0.39    0.00    0.00   47.87
08:13:28 PM    3   50.19    0.00    4.28    0.00    0.00    0.39    0.00    0.00   45.14

中断旉实?%下降C4%左右?/p>

[root@host_77-69 ~]# for i in {1..10000};do    ps -eLf | grep java  | wc -l; echo "-------" ; sleep 2 ; done;

215

-------

217

-------

217

-------

219

-------

219

-------

218

-------

U程池基本处于饱和状态?/p>

 

l果Q?/p>

W一ơ压结果:629毫秒

W二ơ压结果:618毫秒

W三ơ压结果:586毫秒

 

q次CPU:U程Cؓ1:2

相比较CPU和线E数1.2.25的结果有E微的提升,因ؓCPU中断旉比下降了?/p>

 

最l的l论QJVM的垃圑֛Ӟ本地盘IOQ操作系l内存都不会Ҏ应用产生影响Q唯一的元素就是线E池大小的设|?span style="color: #ff0000;">目前试出来的最佳策略是Q?/span>

corePoolSize = cpu + 1

maxPoolSize = 2 *  cpu   

 



已有 0 人发表留aQ猛?>>q里<<-参与讨论


ITeye推荐





]]>
AOP 的简单入?/title><link>http://m.tkk7.com/inter12/archive/2012/09/08/387838.html</link><dc:creator>薛n?/dc:creator><author>薛n?/author><pubDate>Sat, 08 Sep 2012 10:01:00 GMT</pubDate><guid>http://m.tkk7.com/inter12/archive/2012/09/08/387838.html</guid><wfw:comment>http://m.tkk7.com/inter12/comments/387838.html</wfw:comment><comments>http://m.tkk7.com/inter12/archive/2012/09/08/387838.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.tkk7.com/inter12/comments/commentRss/387838.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/inter12/services/trackbacks/387838.html</trackback:ping><description><![CDATA[ <p> </p> <p><span style="font-size: medium;">AOP 的简单入?/span> </p> <p> </p> <p>自己也算是从业多q_对于AOP的概念应该算是听的烂的不能再烂了Q这斚w的书也看的不,但是自己一直没有机会去实践下?/p> <p>乘在q个E微有点I闲的下午,随手玩玩SPRING的AOPQ也谈谈自己对于AOP的理解及其衍生的一些东ѝ?/p> <p> </p> <p><span style="color: #ff6600; font-size: small;"><span style="font-size: medium;">1.一切术语都是纸老虎</span> </span> </p> <p>基本概念Q也可以说是基本术语。Q何一个Y件概忉|出时候,都少不了q个东西。CRM,AOP,SOA{等Q伴随这些东西的都会有相应体pd的术语?/p> <p>我个人的看法是一切术语的出现不是q不是向大众解释清楚qg事到底是怎么一回事Q其主要是基于两个方面考虑Q?/p> <p> </p> <p>1.让自己提Ҏ得系l化Q更h说服力?/p> <p>2.qh大众Q或是迷p那些刚q入q个领域的初学者?/p> <p> </p> <p>两个看似矛盾的因素,其实归结到本质就是将一个简单的东西复杂化ƈqL那些辨别能力的一般的人,大家对于抽象C定程度的东西但是心怀敬畏之心的,然后带着膜拜的心理去接受Q生怕一不小心亵渎了内心的女。扯开来讲现在C会Q官员的道d沦Q其中的一个诱因就是对于敬畏之心的~失Q当一个h无所畏时Q才是最可怕的Q因个时候已l没有Q何约束能U束他的行ؓ?/p> <p> </p> <p>回归正题Q既然提到术语,那么我们将AOP中的那些术语列出来看看?/p> <p>切面QAspectQ、连接点QJoinpointQ、通知QAdviceQ、切入点QPointcutQ?、目标对象(Target ObjectQ、AOP代理QAOP ProxyQ?/p> <p>通知又分为几U:前置通知QBefore adviceQ、后通知QAfter adviceQ、返回后通知QAfter return adviceQ、环l通知QAround adviceQ、抛出异常后通知QAfter throwing adviceQ?{?/p> <p> </p> <p>好了Q现在我们来看看q些术语Q谁能一眼就明白q些东西能告诉我们什么?谁能通畅的理清楚它们之间的关pR开始解释之前,我们看看l基癄上对AOP的定义是什么:</p> <p> </p> <pre class="java" name="code">面向侧面的程序设计(aspect-oriented programmingQAOPQ又译作面向斚w的程序设计、觀點導向編E)是计机U学中的一个术语,指一U程序设计范型。该范型以一U称Z面(aspectQ又译作斚wQ的语言构造ؓ基础Q侧面是一U新的模块化机制Q用来描q分散在对象、类或函C的横切关注点Qcrosscutting concernQ?/pre>   <p> </p> <p>多么单的解释Q就是对于那些在ȝ序业务之外的事情Q我们该怎么设计Q看清楚Q是E序设计Q而不是程序编码,很多地方都将AOP理解成面向切面的~码Q那是错误,AOPU定的是一U设计范型,具体到java上的实现例如aspectJ,例如spring的AOP。再具体到实现技术就是JDK自带的动态代理,cglib的字节码修改{等?span style="color: #ff6600;">AOP != spring AOP ,AOP != cglib 。一个是设计范型Q一个是实现?/span> </p> <p> </p> <p>(q里扯开点说Q一些所谓的架构师喜Ƣ谈概念Q还有h提出架构师更x抽象的东西,普通的码农更关注具象的东西。这些东西本w没错,在大量的实践之后Q我们确实应该去在这大量的实践中归纳Qȝ律,q就是进行抽象。但是,但是Q那些只跟你扯抽象而不落地的架构师Q还是远MQ因Z们不是基于大量的兯后,q行抽象Q他们不q是邯郸学步的抄袭那些真正的架构师的xQƈ转变q观点QTMD是个大忽悠)</p> <p> </p> <p><span style="color: #ff6600; font-size: small;"><span style="font-size: medium;">2.那些ȝ序之外的杂事</span> </span> </p> <p>我们知道Q一个程序是会被~译成计机能识别的机器码,交给机器L行,那么我们想知道机器在执行我们的代码时候,发生的一些事Q例如:</p> <p> </p> <ol> <li>一个输入是否得到我们想要的输出呢?</li> <li>一个函数执行的旉开销是多呢Q?/li> <li>若是一个良好的E序遇到无法处理的异常我们该怎么办呢Q?/li> <li>存在多个数据源,我们需要在多个数据源的更新都完成后Q再提交该怎么处理呢?</li> <li>我们惛_一些我们不认可的请求拒l,那又该怎么处理呢?</li> </ol> <p> </p> <p>当以上的q些杂事出现Ӟ我们该怎么做呢Q一U很单粗暴的方式是编码的这些杂事写入到我们的主要业务程序中Q我惌U方式大家在日常的开发经常能看到Q包括你ȝ一些所谓^台别的产品也是采用q种方式Q笔者现在所在单位的部分产品也是如此。不你爽不爽,老子爽了可以了?/p> <p> </p> <p> </p> <p><span style="color: #ff6600; font-size: medium;">3.上吧Q骚q?/span></p> <p>用个不恰当的比喻来说Q你是个开饭店的,来了很多֮Q当你女服务员在招待֮Ӟ你突然发现XX院长来了Q想来OOXX下。你定了一个流E,来XX院长Q可OOXXQ硬~码的方式就是:</p> <p>1.你女服务员在招待</p> <p>2.XX院长跟她OOXX</p> <p>3.你女服务员在招待</p> <p>4.屌丝来了Q无视之</p> <p>......</p> <p>q个q程中你不管你女服务员是否来例假Q你不关心你x务员是否今天心情不好。嗯Q院长爽了,若是你得C某种回报Q也q好Q爽了;若是什么都得不刎ͼ那可欲哭无泪?/p> <p>如果你够幸的话,有另一个口味美x务员Q她会隐藏技?--z脚。恰巧经学院院长也来了Q这个家伙还喜欢z脚Q那怎么办,那就上吧Q?/p> <p>1.你女服务员在招待</p> <p>2.XX院长跟她OOXX+z脚</p> <p>3.你女服务员在招待</p> <p>4.屌丝来了Q无视之</p> <p>......</p> <p>如果你生意够好Q恰好XX院长又很多,好吧Q你的美女们一直处在XXOO状态中..... 很highQ很happy。但是,我们回到最开始,你ؓ什么要招女服务员?扑֥们来Q是因ؓ你需要她们去招待֮Q一个屌丝在{吃饭没关系Q若是一的屌丝在等吃饭Q你悲剧,没h招待屌丝们了Q因Z的那些服务员都在跟院长们OOXX中,因ؓ命o已经固化到流E中Q你改不了,臛_在你修改程之前。通过我们软g术语来说Q就是不能及时、灵zȝ应对自n内部(你的女们n体、心?和外?屌丝数量)的变化。当Ӟ 你若是铁道部q样的共和国长子Q那是没关系的,让那屌丝们{去吧,因ؓ方圆960万^方公里就此一Ӟ别无分号?/p> <p> </p> <p>若你不是Q哪天觉得自己有点生意有Ҏ不住或是那点生殖器破事被某个黑心Q吃不到葡萄的院长小弟揭发了Q扛不住随之而来的社会舆论压力,不能跟院长们OOXX了,只准对他们笑个,q个时候你得通知那些x务员Q说不准OOXX了,只能看了。若是你只有一家店Q还好,自己喊一壎ͼ重新打印程规章表,若是全国q锁的话...... 一桌的杯具摆在你茶几上?/p>    <p><span style="color: #ff6600; font-size: small;"><span style="font-size: medium;">4.正义化n的出?/span> </span> </p> <p>好了Q扯了这么多Q终于要该AOP兄弟出场了,再不Z计戏都散Z?/p> <p>针对以上的种U问题,我们该怎么处理q些我们店主要生意之外的杂事?OOXX),有什么更好的方式来随时应对种U变化。这个就是我们AOP兄弟惛_的事情,从主业中剥离些杂事,q行单独处理的设计。主业务只关注于自己的领域,对于Ҏ领域的处?OOXX),通过侧面来封装维护,q样使得散落在不同口味美女的Ҏ操作可以很好的管理v来。来D专业点的说明吧Q?/p> <p> </p> <pre class="java" name="code">从主x点中分离出横切关注点是面向侧面的E序设计的核心概c分d注点使得解决特定领域问题的代码从业务逻辑中独立出来,业务逻辑的代码中不再含有针对特定领域问题代码的调用,业务逻辑同特定领域问题的关系通过侧面来封装、维护,q样原本分散在在整个应用E序中的变动可以很好的理h?/pre>   <p> </p> <p>好了QAOP的就是个q么单的东西Q别L那些J杂的spring配置和概忉|语。它只是一U设计范型?/p> <p> </p> <p> </p> <p>l了q么久,让我们来打倒那些纸老虎吧?/p> <p>我开饭店Q屌丝、院长来吃饭Q美女们招待֮ Q这个是我们的主业? ========  目标对象QTarget ObjectQ?是店主我,我开了两个店Q戏院和饭店</p> <p>哦,北大院长来饭店吃饭了                                                            ========  切入点(PointcutQ?他们来我戏院看戏的话Q不,直管饭店的事</p> <p>院长开始吃饭,喝酒了?                                                              ========  q接点(JoinpointQ?Q就是我们的一些行为,院长如果来围观的话,无视之,哥是开饭店的?/p> <p>院长惌女们OOXX?                                                              ========  通知QAdviceQ院长来了,也吃了饭了,那接下来q什么呢Q通知是军_q什?OOXX或是z脚</p> <p>院长除了想OOXX之外Q还x脚,那么怎么办呢Q?                          ========  切面QAspectQ?Q规定院长来了可以干什么,是军_可以有多个通知QOOXX||z脚 或是 OOXX && z脚</p> <p>----------------------------------------------------------------------------------------------------</p> <p>院长惛_饭后z脚                                                                ======== 后通知QAfter adviceQ?/p> <p>院长惛_饭前z脚                                                                ======== 前置通知QBefore adviceQ?/p> <p>院长x据吃饭后的心情决定是OOXXq是z脚                         ======== q回后通知QAfter return adviceQ?/p> <p>院长吃饭吃出脑中风了                                                          ======== 抛出异常后通知QAfter throwing adviceQ这个时候有个通知跛_来:?20Q送医院!</p> <p>院长想饭前洗脚,饭后OOXX                                                 ======== 环绕通知QAround adviceQ?/p> <p> </p> <p>作ؓ老板的我Q应该怎么更好的切入这些洗脚啊QOOXX服务?   ======== AOP代理QAOP ProxyQ怎么在干好招待顾客这件事上切?z脚||OOXX</p> <p> </p> <p>若是上面的这些你q是看不明白的话Q那么我们就兯到spring上,看看到底是g上面事吧。spring中Aspect叫Advisor。Joinpoint叫Weaving。很操蛋Q也很让人无语的术语?/p> <p> </p> <p> </p> <pre class="java" name="code">切面Q? package com.zhaming.aop.advice; import java.lang.reflect.Method; import org.springframework.aop.AfterReturningAdvice; /** * 后置通知 * @author inter12 * */ public class AfterAdvice implements AfterReturningAdvice { @Override public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable { System.out.println("拦截?" + method.getName() + "Ҏ"); System.out.println("z脚"); } } package com.zhaming.aop.advice; import java.lang.reflect.Method; import org.springframework.aop.MethodBeforeAdvice; /** * 前置通知 * * @author inter12 */ public class BeforeAdvice implements MethodBeforeAdvice { @Override public void before(Method method, Object[] args, Object target) throws Throwable { System.out.println("拦截?" + method.getName() + "Ҏ"); System.out.println("OOXX"); } } package com.zhaming.aop.advice; import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; /** * 环绕通知 * * @author inter12 */ public class CompareAdvice implements MethodInterceptor { @Override public Object invoke(MethodInvocation invocation) throws Throwable { Object result = null; String userName = invocation.getArguments()[0].toString(); if (null != userName && userName.equals("yuanzhang")) { System.out.println("院长通过---------------"); result = invocation.proceed(); } else { System.out.println("屌丝拒绝---------------"); } return result; } } 目标对象Q? package com.zhaming.aop.restaurant; public interface RestaurantService { public void zhaodaiguke(String userName); public void weiguan(String userName); } package com.zhaming.aop.restaurant; /** * 目标对象 * * @author inter12 */ public class RestaurantServiceImpl implements RestaurantService { @Override public void zhaodaiguke(String userName) { System.out.println("--------- 姑娘们在招待֮:" + userName); } @Override public void weiguan(String userName) { System.out.println(userName + ":在围?); } } 客户端: package com.zhaming.aop; import org.springframework.context.ApplicationContext; import org.springframework.context.support.FileSystemXmlApplicationContext; import com.zhaming.aop.restaurant.RestaurantService; public class Main { public static void main(String[] args) { ApplicationContext applicationContext = new FileSystemXmlApplicationContext( "http://home/inter12/workspace/Light/src/main/java/appcontext-aop.xml"); RestaurantService bean = (RestaurantService) applicationContext.getBean("restaurantService"); bean.zhaodaiguke("yuanzhang"); bean.zhaodaiguke("diaosi"); } } 配置文gQ? <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"> <!-- 通知 --> <bean id="beforeAdvice" class="com.zhaming.aop.advice.BeforeAdvice"></bean> <bean id="afterAdvice" class="com.zhaming.aop.advice.AfterAdvice"></bean> <bean id="compareAdvice" class="com.zhaming.aop.advice.CompareAdvice"></bean> <!-- 目标对象 --> <bean id="restaurantServiceTarget" class="com.zhaming.aop.restaurant.RestaurantServiceImpl"></bean> <bean id="restaurantService" class="org.springframework.aop.framework.ProxyFactoryBean"> <!-- 拦截那些接口 : 切入?只关心饭店的?-> <property name="proxyInterfaces"> <value>com.zhaming.aop.restaurant.RestaurantService</value> </property> <!-- 对这些方式做那些拦截:切面 --> <property name="interceptorNames"> <list> <!-- <value>beforeAdvice</value> <value>afterAdvice</value> --> <value>compareAdvice</value> </list> </property> <property name="target"> <ref bean="restaurantServiceTarget" /> </property> </bean> </beans></pre>   <p> </p> <p> </p> <p><span style="color: #ff6600; font-size: small;"><span style="font-size: medium;">5.AOP能干什么?</span> </span> </p> <p>现在回头看看最初问的五个问题,那些杂事Q是不是可以对应到Y件中的几个概念:日志记录Q性能l计Q安全控Ӟ事务处理Q异常处理,更衍生的提还有缓存,持久化,同步{?/p> <br/><br/> <span style="color:red;"> <a style="color:red;">已有 <strong>19</strong> 人发表留aQ猛?>><strong>q里</strong><<-参与讨论</a> </span> <br/><br/><br/> <span style="color:#E28822;">ITeye推荐</span> <br/> <ul><li><a href='/clicks/433' target='_blank'><span style="color:red;font-weight:bold;">—Y件h才免语言低担?赴美带薪ȝQ?</span></a></li></ul> <br/><br/><br/> <img src ="http://m.tkk7.com/inter12/aggbug/387838.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/inter12/" target="_blank">薛n?/a> 2012-09-08 18:01 <a href="http://m.tkk7.com/inter12/archive/2012/09/08/387838.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>redis 学习W记4--sortsethttp://m.tkk7.com/inter12/archive/2012/07/26/387839.html薛n?/dc:creator>薛n?/author>Thu, 26 Jul 2012 07:01:00 GMThttp://m.tkk7.com/inter12/archive/2012/07/26/387839.htmlhttp://m.tkk7.com/inter12/comments/387839.htmlhttp://m.tkk7.com/inter12/archive/2012/07/26/387839.html#Feedback0http://m.tkk7.com/inter12/comments/commentRss/387839.htmlhttp://m.tkk7.com/inter12/services/trackbacks/387839.html

redis学习W记3--sortSet

l于到最后一个数据结构了Q加油!Q?/p>

整体l构图:

http://dl.iteye.com/upload/picture/pic/115995/0ee3789f-33e1-35ca-ac65-cbd6b4e4e147.jpg

 

 

1.ZADD

语法Q?ZADD key score value 

释义Q添加执行分数的valueQ?score必须是doublecd的数?/p>

实践Q?/p>

redis 127.0.0.1:6379> zadd z1 1 a 

(integer) 1

redis 127.0.0.1:6379> zadd z1 2 b 

(integer) 1

redis 127.0.0.1:6379> zadd z1 20 bb 

(integer) 1

redis 127.0.0.1:6379> zadd z1 10 ff  

(integer) 1

redis 127.0.0.1:6379> zrange z1 0 -1 

1) "a"

2) "b"

3) "ff"

4) "bb"

 

 

2.ZREM

语法:ZREM key value 

释义Q删除指定value的?/p>

实践Q?/p>

redis 127.0.0.1:6379> ZREM z1 b            // 删除Q指定value

(integer) 1

redis 127.0.0.1:6379> zrange z1 0 -1         

1) "a"

2) "ff"

3) "bb"

 

 

3.ZCARD

语法QZCARD key 

释义Q获取集合L

实践Q?/p>

redis 127.0.0.1:6379> zrange z1 0 -1 

1) "a"

2) "ff"

3) "bb"

redis 127.0.0.1:6379> zcard z1 

(integer) 3

 

4.ZCOUNT

语法:zcount key min max

释义Q计在指定范围内的元素数目

(1 6  ==== 1 < x <= 6        // 括号代表开区间

1 6   ==== 1 <= x <= 6

 

 

实践Q?/p>

redis 127.0.0.1:6379> zrange z1 0 -1 withscores 

1) "a"

2) "1"

3) "ff"

4) "10"

5) "bb"

6) "20"

redis 127.0.0.1:6379> zcount z1 5 10      // 闭区_能取?0

(integer) 1

redis 127.0.0.1:6379> zcount z1 5 (10     //开区间Q无法得?0

(integer) 0

 

5.ZSCORE

语法QZSCORE key value

释义Q获取指定key的分?/p>

实践Q?/p>

redis 127.0.0.1:6379> zrange z1 0 -1 withscores 

1) "a"

2) "1"

3) "ff"

4) "10"

5) "bb"

6) "20"

redis 127.0.0.1:6379> zscore z1 a             // 获取a的分?/p>

"1"

 

6.ZINCRBY

语法QZINCRBY key score value 

释义Q对于指定的valueq行加法操作

实践Q?/p>

redis 127.0.0.1:6379> zrange z1 0 -1 withscores 

1) "a"

2) "1"

3) "ff"

4) "10"

5) "bb"

6) "20"

redis 127.0.0.1:6379> zincrby z1 10 a            // 对于a+10

"11"

redis 127.0.0.1:6379> zrange z1 0 -1 withscores 

1) "ff"

2) "10"

3) "a"

4) "11"

5) "bb"

6) "20"

redis 127.0.0.1:6379> zincrby z1 -3 a          // 对于a-3

"8"

redis 127.0.0.1:6379> zrange z1 0 -1 withscores 

1) "a"

2) "8"

3) "ff"

4) "10"

5) "bb"

6) "20"

 

7.ZRANGE|ZREVRANGE

语法QZRANGE|ZREVRANGE key 

释义Q显C所有列?/p>

redis 127.0.0.1:6379> zrange z1 0 -1 

1) "a"

2) "ff"

3) "bb"

redis 127.0.0.1:6379> zrevrange z1 0 -1 

1) "bb"

2) "ff"

3) "a"

 

8.ZRANGEBYSCORE|ZREVRANGEBYSCORE

语法QZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]

释义Q获取指定范围内的数?/p>

实践Q?/p>

redis 127.0.0.1:6379> zrange z1 0 -1 withscores 

1) "a"

2) "8"

3) "ff"

4) "10"

5) "bb"

6) "20"

redis 127.0.0.1:6379> zrangebyscore z1 -inf +inf   // 在不清楚最大最范围的旉Q可以采用这?-inf +inf 

1) "a"

2) "ff"

3) "bb"

redis 127.0.0.1:6379> zrangebyscore z1 8 10       // 闭区?/p>

1) "a"

2) "ff"

redis 127.0.0.1:6379> zrangebyscore z1 (8 10      // 开区间

1) "ff"

 

 

9.ZRANK|ZREVRANK

语法Qzrank|zremrank  key member

释义Q获取指定值在集合中的排名Q以Q代表第一位 。(序或是逆序Q?/p>

redis 127.0.0.1:6379> zrange z1 0 -1 withscores 

1) "a"

2) "8"

3) "ff"

4) "10"

5) "bb"

6) "20"

redis 127.0.0.1:6379> zrank z1 a 

(integer) 0

redis 127.0.0.1:6379> zrank z1 ff     //序位置

(integer) 1 

redis 127.0.0.1:6379> zrevrank z1 a        //逆序位置

(integer) 2

 

10.ZREMRANGEBYRANK

语法 :ZREMRANGEBYRANK key min max 

释义Q删除指定下标的数据

实践Q?/p>

redis 127.0.0.1:6379> zrange z1 0 -1 

1) "a"

2) "ff"

3) "bb"

redis 127.0.0.1:6379> zremrangebyrank z1 0 1 

(integer) 2

redis 127.0.0.1:6379> zrange z1 0 -1 

1) "bb"

 

11.ZREMRANGEBYSCORE

语法 :ZREMRANGEBYSCORE key min max

释义Q根据指定分数删除数?/p>

实践Q?/p>

redis 127.0.0.1:6379> zrange z1 0 -1 withscores 

1) "bb"

2) "20"

redis 127.0.0.1:6379> ZREMRANGEBYSCORE z1 -inf +inf    // 删除所有的数据 {同? del z1

(integer) 1

redis 127.0.0.1:6379> zrange z1 0 -1 

(empty list or set)

 

12.ZINTERSTORE

语法QZINTERSTORE destination numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE SUM|MIN|MAX]

释义Q?/p>

  计算l定的一个或多个有序集的交集Q其中给?key 的数量必M numkeys 参数指定Qƈ该交集(l果?储存?destination ?/p>

  默认情况下,l果集中某个成员?score 值是所有给定集下该成员 score g?

 

实践Q?/p>

redis 127.0.0.1:6379> zrange s1 0 -1 

1) "a"

2) "b"

3) "c"

redis 127.0.0.1:6379> zrange s2 0 -1 

1) "a"

2) "c"

3) "d"

redis 127.0.0.1:6379> zinterstore s3 2 s1 s2 

(integer) 2

redis 127.0.0.1:6379> zrange s3 0 -1 

1) "a"

2) "c"

redis 127.0.0.1:6379> 

 

13.ZUNIONSTORE

语法QZUNIONSTORE destination numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE SUM|MIN|MAX]

释义Q计给定的一个或多个有序集的qQ其中给?key 的数量必M numkeys 参数指定Qƈ该q(l果?储存?destination ?/p>

默认情况下,l果集中某个成员?score 值是所有给定集下该成员 score g ??/p>

 

WEIGHTS

 使用 WEIGHTS 选项Q你可以?每个 l定有序?分别 指定一个乘法因?multiplication factor)Q每个给定有序集的所有成员的 score 值在传递给聚合函数(aggregation function)之前都要先乘以该有序集的因子?/p>

 如果没有指定 WEIGHTS 选项Q乘法因子默认设|ؓ 1 ?/p>

 

AGGREGATE

 使用 AGGREGATE 选项Q你可以指定q的结果集的聚合方式?/p>

 默认使用的参?SUM Q可以将所有集合中某个成员?score g ?作ؓl果集中该成员的 score |使用参数 MIN Q可以将所有集合中某个成员?最?score g为结果集中该成员?score |而参?MAX 则是所有集合中某个成员?最?score g为结果集中该成员?score 倹{?/p>

 

实践Q?/p>

redis 127.0.0.1:6379> zunionstore s3 2 s1 s2 

(integer) 4

redis 127.0.0.1:6379> zrange s3 0 -1 

1) "b"

2) "a"

3) "c"

4) "d"

redis 127.0.0.1:6379> 




已有 0 人发表留aQ猛?>>q里<<-参与讨论


ITeye推荐





]]>
redis 学习W记3--sethttp://m.tkk7.com/inter12/archive/2012/07/25/387840.html薛n?/dc:creator>薛n?/author>Wed, 25 Jul 2012 10:36:00 GMThttp://m.tkk7.com/inter12/archive/2012/07/25/387840.htmlhttp://m.tkk7.com/inter12/comments/387840.htmlhttp://m.tkk7.com/inter12/archive/2012/07/25/387840.html#Feedback0http://m.tkk7.com/inter12/comments/commentRss/387840.htmlhttp://m.tkk7.com/inter12/services/trackbacks/387840.html 

redis学习W记3--set

 

list:有序且,允许重复数据的链?存在POP PUSH的概?/p>

set: 无需序,不能重复的集?主要是ADD 

sortSetQ有序,不能重复的集合?/p>

 

整体l构图:

http://dl.iteye.com/upload/picture/pic/115943/f6e6971a-0216-3fe3-b89c-4ec5b53b762a.jpg

 

 

1.SADD 新增元素

语法Q?sadd key value 

实践Q?/p>

redis 127.0.0.1:6379> sadd s1 1

(integer) 1

redis 127.0.0.1:6379> sadd s1 2 

(integer) 1

redis 127.0.0.1:6379> sadd s2 3 

(integer) 1

redis 127.0.0.1:6379> sadd s1 1      // 重复数据不会被添?/p>

(integer) 0

redis 127.0.0.1:6379>

 

2.SREM 删除元素

语法Qsrem key value 

实践Q?/p>

redis 127.0.0.1:6379> smembers s1 

1) "1"

2) "2"

redis 127.0.0.1:6379> srem s1 1       // 删除s1中的1元素

(integer) 1

redis 127.0.0.1:6379> smembers s1 

1) "2"

redis 127.0.0.1:6379> 

 

3.SMEMBERS 列出所有信?cMlist?lrange

语法Qsmembers key 

实践Q?/p>

redis 127.0.0.1:6379> smembers s1 

1) "2"

redis 127.0.0.1:6379> 

 

 

4.SISMEMBER 判断是否存在该元?/p>

语法Qsismember key value 

1:存在该元?/p>

0:不存?/p>

 

实践Q?/p>

redis 127.0.0.1:6379> sismember s1 1   存在的元素返?

(integer) 1

redis 127.0.0.1:6379> sismember s1 3   不存在的元素q回0

(integer) 0

redis 127.0.0.1:6379>

 

5.SCARD 计算集合中元素L size

语法Qscard key 

实践Q?/p>

redis 127.0.0.1:6379> scard s1     // q回集合中元素个?/p>

(integer) 2

redis 127.0.0.1:6379> 

 

6.SMOVE 集合中一个元素{Ud另一个集合中

语法: smove  source destination value 

实践Q?/p>

redis 127.0.0.1:6379> smembers s1 

1) "1"

2) "2"

redis 127.0.0.1:6379> smembers s2

(empty list or set)

redis 127.0.0.1:6379> smove s1 s2 1    // S1中的1UdCS2?/p>

(integer) 1

redis 127.0.0.1:6379> smembers s1 

1) "2"

redis 127.0.0.1:6379> smembers s2

1) "1"

redis 127.0.0.1:6379>

 

7.SPOP 随机弹出一个元?/p>

语法Q?spop key 

实践Q?/p>

redis 127.0.0.1:6379> smembers s1 

1) "1"

2) "2"

3) "3"

4) "4"

redis 127.0.0.1:6379> spop s1           // 随机弹出一个元?/p>

"3"

redis 127.0.0.1:6379> smembers s1 

1) "1"

2) "2"

3) "4"

redis 127.0.0.1:6379> 

 

8.SRANDMEMBER 随机获取一个元素,但是不弹出集?q个是跟SPOP唯一的区?/p>

语法: SRANDMEMBER

实践Q?/p>

redis 127.0.0.1:6379> smembers s1 

1) "1"

2) "2"

3) "4"

redis 127.0.0.1:6379> SRANDMEMBER s1   //  随机取得一个数据,但是元素不会丢失

"4"

redis 127.0.0.1:6379> smembers s1 

1) "1"

2) "2"

3) "4"

redis 127.0.0.1:6379>

 

9.SINTER 取两个集合的交集

语法QSINTER key1 key2 

实践Q?/p>

redis 127.0.0.1:6379> smembers s2 

1) "1"

2) "10"

redis 127.0.0.1:6379> smembers s1 

1) "1"

2) "2"

3) "4"

redis 127.0.0.1:6379> sinter s1 s2    // 两个集合共同的元素是 1 

1) "1"

redis 127.0.0.1:6379>

 

10.SINTERSTORE 取两个集合的交集q保存到另一个集合中 

语法QSINTERSTORE destination key1 key2 

实践Q?/p>

redis 127.0.0.1:6379> smembers s1

1) "1"

2) "2"

3) "3"

redis 127.0.0.1:6379> smembers s2

1) "1"

2) "10"

redis 127.0.0.1:6379> smembers s3                 //q个时候S3是空?/p>

(empty list or set)

redis 127.0.0.1:6379> sinterstore s3  s1 s2       //取两个的交集q保存到s3 ?/p>

(integer) 1

redis 127.0.0.1:6379> smembers s3

1) "1"

redis 127.0.0.1:6379>

 

11.SUNION  取两个集合的q 

语法QSUNION key1 key2 

实践Q?/p>

redis 127.0.0.1:6379> smembers s1

1) "1"

2) "2"

3) "3"

redis 127.0.0.1:6379> smembers s2

1) "1"

2) "10"

redis 127.0.0.1:6379> sunion s1 s2              // 取得两个集合的ƈ?/p>

1) "1"

2) "2"

3) "3"

4) "10"

redis 127.0.0.1:6379> 

 

12.SUNIONSTORE 取两个集合的qq保存到另一个集合中 

语法: SUNIONSTORE destination key1 key2  

实践Q?/p>

redis 127.0.0.1:6379> smembers s1

1) "1"

2) "2"

3) "3"

redis 127.0.0.1:6379> smembers s2

1) "1"

2) "10"

redis 127.0.0.1:6379> sunionstore  s4 s1 s2 

(integer) 4

redis 127.0.0.1:6379> smembers s4

1) "1"

2) "2"

3) "3"

4) "10"

redis 127.0.0.1:6379> 

 

13.SDIFF 取两个集合的差集

语法QSDIFF key1 key2

实践Q?/p>

redis 127.0.0.1:6379> smembers s1

1) "1"

2) "2"

3) "3"

redis 127.0.0.1:6379> smembers s2

1) "1"

2) "10"

redis 127.0.0.1:6379> sdiff s1 s2    // 获取的是两个之间的差?/p>

1) "2"

2) "3"

redis 127.0.0.1:6379> 

 

14.SDIFFSTORE 取两个集合的差集 q保存到W三个集合中

语法:SDIFFSTORE key1 key2 diffSet

实践Q?/p>

redis 127.0.0.1:6379> smembers s1

1) "1"

2) "2"

3) "3"

redis 127.0.0.1:6379> smembers s2

1) "1"

2) "10"

redis 127.0.0.1:6379> sdiffstore s5  s1 s2    // 差集的数据保存到s5中?/p>

(integer) 2

redis 127.0.0.1:6379> smembers s5

1) "2"

2) "3"




已有 0 人发表留aQ猛?>>q里<<-参与讨论


ITeye推荐





]]>
redis 学习W记2--Listhttp://m.tkk7.com/inter12/archive/2012/07/25/387841.html薛n?/dc:creator>薛n?/author>Wed, 25 Jul 2012 08:15:00 GMThttp://m.tkk7.com/inter12/archive/2012/07/25/387841.htmlhttp://m.tkk7.com/inter12/comments/387841.htmlhttp://m.tkk7.com/inter12/archive/2012/07/25/387841.html#Feedback0http://m.tkk7.com/inter12/comments/commentRss/387841.htmlhttp://m.tkk7.com/inter12/services/trackbacks/387841.htmlLIST 整体l构?/p>

 

囄的太大了Q只能放地址Q?/p>

http://dl.iteye.com/upload/picture/pic/115935/8e96f42d-3a7b-3cea-85ae-997496aa9521.jpg

 

LIST列表的操作,可想而知Q对于列表我们需要的具备的功能列?/p>

加入列表Q?/p>

  从头部加?  LPUSH 

  从底部加?  RPUSH

弹出列表

  从头部弹?  LPOP

  从底部弹?  RPOP

截取子列?    LRANGE

计算列表的长?LLEN

 

 

实践Q?/p>

redis 127.0.0.1:6379> rpush l2 1     // 从底部添加一个元?/p>

(integer) 1

redis 127.0.0.1:6379> rpush l2 2 

(integer) 2

redis 127.0.0.1:6379> lrange l2 0 -1 // 展示所有的元素  -1 代表所?/p>

1) "1"

2) "2"

redis 127.0.0.1:6379> lpush l2 3 

(integer) 3

redis 127.0.0.1:6379> lrange l2 0 -1 

1) "3"

2) "1"

3) "2"

redis 127.0.0.1:6379> lpop l2       // 从头部弹Z个元?/p>

"3"

redis 127.0.0.1:6379> rpop l2       // 从尾部弹Z个元?/p>

"2"

redis 127.0.0.1:6379> llen l2       // 计算队列的长?/p>

(integer) 1

 

扩展

1.1 LPUSHX  当且队列存在的情况下 在头部插入数据?/p>

 

LPUSHX key value

 

实践Q?/p>

redis 127.0.0.1:6379> LLEN empty1            

(integer) 0

redis 127.0.0.1:6379> lpushx empty1 hh    // 数据推入一个空的队列,l果p|

(integer) 0

redis 127.0.0.1:6379> lpush l3 hh 

(integer) 1

redis 127.0.0.1:6379> lpushx l3 hh2      // 数据推入一个存在的队列头部Q成?/p>

(integer) 2

redis 127.0.0.1:6379> lrange l3 0 -1 

1) "hh2"

2) "hh"

 

1.2 RPUSHX 当且队列存在的情况下 在尾部插入数? 基本同LPUSHX

redis 127.0.0.1:6379> rpushx empty1 hh3    // 试数据推入不存在队列的尾部,p|?/p>

(integer) 0

redis 127.0.0.1:6379> rpushx l3 hh3        // 数据推入存在队列的ַQ成功?/p>

(integer) 3

redis 127.0.0.1:6379> lrange l3 0 -1

1) "hh2"

2) "hh"

3) "hh3"

 

1.3 BLPOP 对于LPOP的扩?Q阻塞式的获取数?/p>

BLPOP key [key ...] timeout

 

它是 LPOP 命o的阻塞版本,当给定列表内没有M元素可供弹出的时候,q接被 BLPOP 命odQ直到等待超时或发现可弹出元素ؓ止?/p>

当给定多?key 参数Ӟ按参?key 的先后顺序依ơ检查各个列表,弹出W一个非I列表的头元素?/p>

 

假设现在有三个队?job 为空 Q?command  request 不ؓI?。那么就开始轮训所有的key Q若是空Q则跌 。执行顺序ؓ job ==> command ==> request

 

实践Q?/p>

redis 127.0.0.1:6379> del job 

(integer) 0

redis 127.0.0.1:6379> lpush command hh 

(integer) 1

redis 127.0.0.1:6379> lpush request kk 

(integer) 1

redis 127.0.0.1:6379> blpop job command kk 

(error) ERR timeout is not an integer or out of range

redis 127.0.0.1:6379> blpop job command kk  100 

1) "command"

2) "hh"

redis 127.0.0.1:6379>

 

查看其是如何d?/p>

在第一个图片中Q上面那个终端一直阻塞着?/p>

 

在第二个l端中输入数据后Q上面终端取得数据ƈq回?

 

1.4 BRPOP 对于rpop的扩展,原理基本同BLPOP

 

2.LREM

语法QLREM key count value

释义Q根据参?count 的|U除列表中与参数 value 相等的元素?/p>

count 的值可以是以下几种Q?/p>

  count > 0 : 从表头开始向表尾搜烦Q移除与 value 相等的元素,数量?count ?/p>

  count < 0 : 从表ּ始向表头搜烦Q移除与 value 相等的元素,数量?count 的绝对倹{?/p>

  count = 0 : U除表中所有与 value 相等的倹{?/p>

 

实践Q?/p>

redis 127.0.0.1:6379> lpush l1 hello 

(integer) 1

redis 127.0.0.1:6379> lpush l1 world 

(integer) 2

redis 127.0.0.1:6379> lpush l1 hello 

(integer) 3

redis 127.0.0.1:6379> lpush l1 world 

(integer) 4

redis 127.0.0.1:6379> lpush l1 hello 

(integer) 5

redis 127.0.0.1:6379> lrange l1 0 -1 

1) "hello"

2) "world"

3) "hello"

4) "world"

5) "hello"

redis 127.0.0.1:6379>                       // 数据准备完成

 

redis 127.0.0.1:6379> lrem l1 2 hello      // 从头部开始扫描,U除了两个hello 

(integer) 2

redis 127.0.0.1:6379> lrem l1 -1 hello     // 从尾部开始扫描,U除了一个hello

(integer) 1

redis 127.0.0.1:6379> lrange l1 0 -1       // 现在只剩?world?/p>

1) "world"

2) "world"

redis 127.0.0.1:6379> lrem l1 0 world     // U除队中所有的world 

(integer) 2

redis 127.0.0.1:6379> lrange l1 0 -1      // 已经被清IZ?/p>

(empty list or set)

redis 127.0.0.1:6379> 

 

3.LSET

语法QLSET key index value

释义Q将列表 key 下标?index 的元素的D|ؓ value ?/p>

实践Q?/p>

redis 127.0.0.1:6379> lpush l1 hello 

(integer) 1

redis 127.0.0.1:6379> lpush l1 world 

(integer) 2

redis 127.0.0.1:6379> lset l1 1  ---      // 下标?的数据被替换?--- ?/p>

OK

redis 127.0.0.1:6379> lrange l1 0 -1

1) "world"

2) "---"

redis 127.0.0.1:6379> lset l1 3 hh       // 出下标q行讄的话Q报?/p>

(error) ERR index out of range

redis 127.0.0.1:6379> exist l2 

(error) ERR unknown command 'exist'

redis 127.0.0.1:6379> exists l2          // 对不存在的队列进行设|的话,报错

(integer) 0

redis 127.0.0.1:6379> lset l2 0 hh 

(error) ERR no such key

redis 127.0.0.1:6379> 

 

 

4 LTRIM

语法QLTRIM key start stop

释义Q对一个列表进行修?trim)Q就是说Q让列表只保留指定区间内的元素,不在指定区间之内的元素都被删除?/p>

 出范围的下标g会引起错误?/p>

 如果 start 下标比列表的最大下?end ( LLEN list 减去 1 )q要大,或?start > stop Q?LTRIM q回一个空列表(因ؓ LTRIM 已经整个列表清I??/p>

 如果 stop 下标?end 下标q要大,Redis?stop 的D|ؓ end 

 

实践Q?/p>

redis 127.0.0.1:6379> lrange l1 0 -1    // 新徏一个队列?/p>

1) "h"

2) "e"

3) "l"

4) "l"

5) "o"

redis 127.0.0.1:6379> ltrim l1 0 3     // 只截取前四个 

OK

redis 127.0.0.1:6379> lrange l1 0 -1

1) "h"

2) "e"

3) "l"

4) "l"

redis 127.0.0.1:6379> ltrim l1 0 10    // stop下标大于队列长度 ?stop=队列长度

OK

redis 127.0.0.1:6379> lrange l1 0 -1

1) "h"

2) "e"

3) "l"

4) "l"

redis 127.0.0.1:6379> lset l1 10 20  // start stop 都大?队列长度 ?start < stop 清空队列

(empty list or set)

redis 127.0.0.1:6379> ltrim l1 3 1     // start  < stop 清空队列

OK

redis 127.0.0.1:6379> lrange l1 10 20 

(empty list or set)

 

5.LINDEX

语法QLINDEX key index

释义Q返回列?key 中,下标?index 的元素?/p>

 下标(index)参数 start ?stop 都以 0 为底Q也是_?0 表示列表的第一个元素,?1 表示列表的第二个元素Q以此类推?/p>

 你也可以使用负数下标Q以 -1 表示列表的最后一个元素, -2 表示列表的倒数W二个元素,以此cL?/p>

 

实践Q?/p>

redis 127.0.0.1:6379> lpush l1 1 

(integer) 1

redis 127.0.0.1:6379> lpush l1 2

(integer) 2

redis 127.0.0.1:6379> lpush l1 3

(integer) 3

redis 127.0.0.1:6379> lindex l1 0            // 取下标ؓ0的数?/p>

"3"

redis 127.0.0.1:6379> lrange l1 0 -1 

1) "3"

2) "2"

3) "1"

redis 127.0.0.1:6379> lindex l1 -1          // 取最后一个数?/p>

"1"

redis 127.0.0.1:6379> 

 

6. LINSERT  cM于LSET,一个是Ҏ下标来插入,一个是Ҏpivot来插入数据?/p>

语法QLINSERT key BEFORE|AFTER pivot value

释义Q将?value 插入到列?key 当中Q位于?pivot 之前或之后?/p>

  ?pivot 不存在于列表 key Ӟ不执行Q何操作?/p>

  ?key 不存在时Q?key 被视为空列表Q不执行M操作?/p>

  如果 key 不是列表cdQ返回一个错误?/p>

 

实践Q?/p>

redis 127.0.0.1:6379> lrange l1 0 -1 

1) "redis"

2) "hello"

3) "world"

4) "hello"

redis 127.0.0.1:6379> linsert l1 after hello after-insert          // 在第一个找到的hello后面插入了一个数据?/p>

(integer) 5

redis 127.0.0.1:6379> lrange l1 0 -1 

1) "redis"

2) "hello"

3) "after-insert"

4) "world"

5) "hello"

redis 127.0.0.1:6379> linsert l1 before hello before-insert       // 在第一个找到的hello前面插入了一个数据?/p>

(integer) 6

redis 127.0.0.1:6379> lrange l1 0 -1 

1) "redis"

2) "before-insert"

3) "hello"

4) "after-insert"

5) "world"

6) "hello"

redis 127.0.0.1:6379> linsert l1 before hoho before-insert       // 对于 pivot 不存在的列表Q插入失?/p>

(integer) -1

redis 127.0.0.1:6379> lrange l1 0 -1 

1) "redis"

2) "before-insert"

3) "hello"

4) "after-insert"

5) "world"

6) "hello"

redis 127.0.0.1:6379> linsert l2 before hoho before-insert       // 插入一个空列表Q直接报?/p>

(integer) 0

 

7. RPOPLPUSH 

语法QRPOPLPUSH source destination

释义Q?/p>

命o RPOPLPUSH 在一个原子时间内Q执行以下两个动作:

 列?source 中的最后一个元?օ?弹出Qƈq回l客L?/p>

 ?source 弹出的元素插入到列表 destination Q作?destination 列表的的头元素?/p>

举个例子Q你有两个列?source ?destination Q?source 列表有元?a, b, c Q?destination 列表有元?x, y, z Q执?RPOPLPUSH source destination 之后Q?source 列表包含元素 a, b Q?destination 列表包含元素 c, x, y, z Qƈ且元?c 会被q回l客L?/p>

 如果 source 不存在,?nil 被返回,q且不执行其他动作?/p>

 如果 source ?destination 相同Q则列表中的表尾元素被移动到表头Qƈq回该元素,可以把这U特D情况视作列表的旋{(rotation)操作?/p>

 

实践Q?/p>

redis 127.0.0.1:6379> lrange l1 0 -1 

1) "c"

2) "b"

3) "a"

redis 127.0.0.1:6379> lrange l2 0 -1

1) "3"

2) "2"

3) "1"

redis 127.0.0.1:6379> rpoplpush l1 l2     //l1N的数据弹入l2的头?q将q个弹出的数据返?/p>

"a"

redis 127.0.0.1:6379> lrange l1 0 -1 

1) "c"

2) "b"

redis 127.0.0.1:6379> lrange l2 0 -1 

1) "a"

2) "3"

3) "2"

4) "1"

redis 127.0.0.1:6379>

 

8. BRPOPLPUSH 

语法QBRPOPLPUSH source destination timeout

释义QBRPOPLPUSH ?RPOPLPUSH 的阻塞版本,当给定列?source 不ؓI时Q?BRPOPLPUSH 的表现和 RPOPLPUSH 一栗?/p>

   当列?source 为空Ӟ BRPOPLPUSH 命o阻塞连接,直到{待时Q或有另一个客L?source 执行 LPUSH ?RPUSH 命o为止?/p>

   时参数 timeout 接受一个以Uؓ单位的数字作为倹{超时参数设?0 表示d旉可以无限期g?block indefinitely) ?/p>

 

实践Q?/p>

我们讄{超时时间ؓ1000 

 

在另一个客Ld数据后,p{UM数据

 

 

 



已有 0 人发表留aQ猛?>>q里<<-参与讨论


ITeye推荐





]]>
redis学习W记1--stringhttp://m.tkk7.com/inter12/archive/2012/07/24/387842.html薛n?/dc:creator>薛n?/author>Tue, 24 Jul 2012 09:29:00 GMThttp://m.tkk7.com/inter12/archive/2012/07/24/387842.htmlhttp://m.tkk7.com/inter12/comments/387842.htmlhttp://m.tkk7.com/inter12/archive/2012/07/24/387842.html#Feedback0http://m.tkk7.com/inter12/comments/commentRss/387842.htmlhttp://m.tkk7.com/inter12/services/trackbacks/387842.html 

NOSQL的学习笔讎ͼ

1.最基本的命?/p>

怿所有的NOSQL都会提供了命令:GET SET DEL 

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

redis 127.0.0.1:6379> set ee 10 

OK

redis 127.0.0.1:6379> get ee 

"10"

redis 127.0.0.1:6379> del ee              // q回?1:代表正确 0Q代表错?/p>

(integer) 1

redis 127.0.0.1:6379> get ee  

(nil)

redis 127.0.0.1:6379>

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

 

del key1 key2 key3  //可删除多个key

 

 

扩展Q?/p>

1.1 SETNX:讄一个|如果不存在的?已经存在则不新增.对于SET的扩展?/p>

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

redis 127.0.0.1:6379> set ee 10 

OK

redis 127.0.0.1:6379> setnx ee 20 

(integer) 0

redis 127.0.0.1:6379> get ee             // 因ؓ之前存在ee  所以ee的值ƈ没有发生变化?/p>

"10"

redis 127.0.0.1:6379> setnx aa 20        //  aa 之前不存在,所以设|成功!

(integer) 1

redis 127.0.0.1:6379> get aa 

"20"

redis 127.0.0.1:6379> 

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

 

1.2 SETEX 讄q期旉Q对于SET的扩展。若是已l存在,会覆盖原来的倹{?/p>

语法:

SETEX key seconds value

 

要求版本Q?gt;= 2.0.0

 

实践Q?/p>

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

redis 127.0.0.1:6379> setex ee 10 20 

OK

redis 127.0.0.1:6379> get ee 

"20"

redis 127.0.0.1:6379> ttl ee 

(integer) 4

redis 127.0.0.1:6379> ttl ee 

(integer) 2

redis 127.0.0.1:6379> ttl ee 

(integer) -1

redis 127.0.0.1:6379> get ee 

(nil)

redis 127.0.0.1:6379> 

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

 

限制Q?/p>

{同于一下语句,不过是一个原子性的操作Q很适合做缓存用?/p>

SET key value

EXPIRE key seconds  # 讄生存旉

 

1.3 PSETEX  对于 SETEX的再ơ扩展,唯一的区别是以毫Uؓ单位Q不是以Uؓ单位

语法Q?/p>

PSETEX key milliseconds value

 

要求版本Q?gt;= 2.6.0

实践Q?/p>

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

redis 127.0.0.1:6379> setex ee 10 20 

OK

redis 127.0.0.1:6379> get ee 

"20"

redis 127.0.0.1:6379> ttl ee 

(integer) 4

redis 127.0.0.1:6379> ttl ee 

(integer) 2

redis 127.0.0.1:6379> ttl ee 

(integer) -1

redis 127.0.0.1:6379> get ee 

(nil)

redis 127.0.0.1:6379> 

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

 

1.4 MGET , MSET

获取多个值或是设|多个倹{?/p>

 

MSET Q替换旧|原子操作?/p>

 

实践Q?/p>

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

redis 127.0.0.1:6379> mset key1 haha key2 hehe 

OK

redis 127.0.0.1:6379> mget key1 key2 

1) "haha"

2) "hehe"

redis 127.0.0.1:6379> 

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

 

1.5 MSETNX Q设|多个key value,仅当key存在? 

MSETNX key value [key value ...] 

既然有setnx ׃?q个命o

 

实践Q?/p>

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

redis 127.0.0.1:6379> msetnx key1 hehe key3 hoho              //因ؓq是一个原子的操作Q所以key1已经存在Q所以整体失败了Q?/p>

(integer) 0

redis 127.0.0.1:6379> mget key1 key2 key3                     // 找不到所要的key3

1) "haha"

2) "hehe"

3) (nil)

redis 127.0.0.1:6379> 

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

 

1.6 GETSET

GETSET key value 讄一个key的valueQƈ获取讄前的?。相当于重置功能?/p>

 

 

实践Q?/p>

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

redis 127.0.0.1:6379> incrby count 10 

(integer) 10

redis 127.0.0.1:6379> getset count "5"    // q个时候返回的?0Q不?

"10"

redis 127.0.0.1:6379> get count 

"5"

redis 127.0.0.1:6379> 

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

有时我们需要获取计数器的|q且自动其重置?

 

1.7 GETRANGE 获取存储在一个关键的一个子字符?/p>

 

实践Q?/p>

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

redis 127.0.0.1:6379> set longworld "hello world!"

OK

redis 127.0.0.1:6379> getrange  longworld 0 5 

"hello "

redis 127.0.0.1:6379> getrange longworld -6 -1 

"world!"

redis 127.0.0.1:6379> 

redis 127.0.0.1:6379> getrange longworld 5 100     // 出范围的数据只取最后位

" world!"

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

 

1.8 SETRANGE cM于GETRANGE 覆盖在指定的偏移量开始的关键字符串的一部分

 

实践Q?/p>

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

redis 127.0.0.1:6379> setrange longworld 6 "redis"

(integer) 12

redis 127.0.0.1:6379> get longworld 

"hello redis!"

redis 127.0.0.1:6379> 

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

 

1.9 STRLEN  计算长度

语法Q?/p>

STRLEN key 

 

实践Q?/p>

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

redis 127.0.0.1:6379> strlen longworld 

(integer) 12

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

 

1.10 append q加数据 Qsetrange是截取字W?/p>

语法Q?/p>

append key str

 

实践Q?/p>

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

redis 127.0.0.1:6379> append longworld "!!!"

(integer) 15

redis 127.0.0.1:6379> get longworld 

"hello redis!!!!"

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

 

 

3.INCR :对于一个数值做递增Q步伐是1?/p>

限制Q?/p>

只允许对于数值类型做操作Q若是字W串cd则报错?/p>

 

是否U程安全Q是的,是一个原子操作,不用担心多线Eƈ发修改同一个值得问题?/p>

即不会出C下情况:

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

    Client A reads count as 10.

    Client B reads count as 10.

    Client A increments 10 and sets count to 11.

    Client B increments 10 and sets count to 11.

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

 

若是希望递增的频率不?呢,那么使用INCRBY 

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

redis 127.0.0.1:6379> set ee 10 

OK

redis 127.0.0.1:6379> incrby ee 2     // W三个参数是步频

(integer) 12

redis 127.0.0.1:6379> get ee 

"12"

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

 

扩展Q?/p>

INCR &&INCRBY 对应的命令是 DECR QDECRBY

 

4.如何讄一个key的过期时间呢Q?/p>

单,通过 EXPIRE来设|,通过TTL命o查看?/p>

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

redis 127.0.0.1:6379> set ee 10

OK

redis 127.0.0.1:6379> expire ee 10          // 讄q期旉?0U?/p>

(integer) 1

redis 127.0.0.1:6379> ttl ee

(integer) 8

redis 127.0.0.1:6379> ttl ee

(integer) 3

redis 127.0.0.1:6379> ttl ee                // 已经q期了?/p>

(integer) -1

redis 127.0.0.1:6379> get ee                // 已经取不到g  

(nil)

redis 127.0.0.1:6379>                  

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

 

若是不设|expire Q只是set 一个值后Q再通过ttl 查看 q回l果?-1 Q代表永q不q期?/p>

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

redis 127.0.0.1:6379> set ee 10 

OK

redis 127.0.0.1:6379> ttl ee 

(integer) -1

redis 127.0.0.1:6379> get ee 

"10"

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

 

一个整体结构图Q?/p>

囑֤?q是自己贴地址吧:

http://dl.iteye.com/upload/picture/pic/115893/840bfd7b-765e-3884-8253-0c7b3ec9db4c.jpg

 

 



已有 0 人发表留aQ猛?>>q里<<-参与讨论


ITeye推荐





]]>
redis 安装W记http://m.tkk7.com/inter12/archive/2012/07/24/387843.html薛n?/dc:creator>薛n?/author>Tue, 24 Jul 2012 09:26:00 GMThttp://m.tkk7.com/inter12/archive/2012/07/24/387843.htmlhttp://m.tkk7.com/inter12/comments/387843.htmlhttp://m.tkk7.com/inter12/archive/2012/07/24/387843.html#Feedback0http://m.tkk7.com/inter12/comments/commentRss/387843.htmlhttp://m.tkk7.com/inter12/services/trackbacks/387843.html1.redis的安?/strong>

wget http://download.redis.io/redis-stable.tar.gz

tar xvzf redis-stable.tar.gz

cd redis-stable

make

如此已l安装完成了Q当然也可以采用make test来看看安装是否正?/p>

 

基本常用命oQ?/p>

redis-server Q运行一个redisserver

redis-cli :redis命o行版本的客户端,同本地或是远Eredis服务q行交互

redis-benchmark : 查redis服务性能的命?/p>

redis-check-aof and redis-check-dump are useful in the rare event of corrupted data files.

 

若是在make的时候没有将redis-serverQredis-cli拯?usr/local/bin目录下,那么手工拯下?/p>

 

sudo cp redis-server /usr/local/bin/

sudo cp redis-cli /usr/local/bin/

 

2.启动redis

inter12@inter12-VirtualBox:~$ redis-server

[2233] 27 Jun 09:23:04 # Warning: no config file specified, using the default config. In order to specify a config file use 'redis-server /path/to/redis.conf'

[2233] 27 Jun 09:23:04 * Server started, Redis version 2.4.15

[2233] 27 Jun 09:23:04 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.

[2233] 27 Jun 09:23:04 * DB loaded from disk: 0 seconds

[2233] 27 Jun 09:23:04 * The server is now ready to accept connections on port 6379

[2233] 27 Jun 09:23:04 - DB 0: 1 keys (0 volatile) in 4 slots HT.

[2233] 27 Jun 09:23:04 - 0 clients connected (0 slaves), 717624 bytes in use

 

不带M参数的情况,采用的是默认的配|文件。这个只适用于开发环境,生成环境需要自己制定一个配|文件。具体命令是Q?redis-server /etc/redis.conf 

 

3.查redis是否正常工作

inter12@inter12-VirtualBox:~$ redis-cli ping

PONG

 

q回PONG׃表是OK的?/p>

 

4.redis的常用命?/strong>

redis 127.0.0.1:6379> set haha 'zhaoming'

OK

redis 127.0.0.1:6379> get haha

"zhaoming"

 

所有完整的命o可见:

http://redis.readthedocs.org/en/latest/

 

q有所有可用客LQ?/p>

http://redis.io/clients

 

5.redis的持久化

因ؓ是内存型的NOSQLQ有两种方式?.使用save命oQ会数据刷新到文g中?.采用redis-cli shutdown 会将内存中数据刷新到文g?/p>

更详l的可见Q?/p>

http://redis.io/topics/persistence

 

6.正确的部|redis

1.采用界面部v

2.在linux上,采用一个初始化脚本部v(更推荐这U?

 

如何采用W二U进行部|呢?/p>

s1)建立配置文g及数据文件目?/p>

mkdir /etc/redis 

mkdir /var/redis 

 

s2)初始化脚本攑ֈ/etc/init.d目录?q徏议根据端口号q行文g命名

cp /home/inter12/install/soft/redis/redis-stable/utils/redis_init_script /etc/init.d/redis_6379

~辑 /etc/init.d/redis_6379 Q确保端口是你想讄的?/p>

 

s3)拯redis.conf?/etc/redis目录?/p>

sudo cp /home/inter12/install/soft/redis/redis-stable/redis.conf /etc/redis/6379.conf

 

s4)?var/redis目录下徏立一个redis实例对应的目?/p>

mkdir /var/redis/6379 

 

s5)修改配置文g

讄daemonize 为yes(默认是no)

讄pidfile ?/var/run/redis_6379.pid(可以改变端口)

讄日志U别loglevel

讄logfile ?/var/log/redis_6379.log

讄 dir ?/var/redis/6379 (q个是最重要?

 

s6)最后添加初始化配置文g到所有运行别下

sudo update-rc.d redis_6379 defaults   // 告诉pȝ启动时候,自动执行redis_6379q个脚本?/p>

 

如此搞定了所有配|修改工作,可以如此启动了Q?/p>

/etc/init.d/redis_6379 start

 

通过以下方式保q行成功Q?/p>

通过 redis-cli 试q接

q行 redis-cli Q然?save 查是否生成一个数据文件到 /var/redis/6379/目录下?(应该能找C?dump.rdb文g).

查是否在 /var/redis/6379/目录下生成文?/p>

重启后,再次查以上步骤?/p>

已有 0 人发表留aQ猛?>>q里<<-参与讨论


ITeye推荐






]]>
AMQP--rabbitmq--1http://m.tkk7.com/inter12/archive/2012/07/17/387844.html薛n?/dc:creator>薛n?/author>Tue, 17 Jul 2012 09:39:00 GMThttp://m.tkk7.com/inter12/archive/2012/07/17/387844.htmlhttp://m.tkk7.com/inter12/comments/387844.htmlhttp://m.tkk7.com/inter12/archive/2012/07/17/387844.html#Feedback0http://m.tkk7.com/inter12/comments/commentRss/387844.htmlhttp://m.tkk7.com/inter12/services/trackbacks/387844.html1.基本安装

分ؓ server  + client 

 

server的安装:

 

1.d deb http://www.rabbitmq.com/debian/ testing main ?/etc/apt/sources.list

 

2.apt-get update.

 

3.sudo apt-get install rabbitmq-server

q个步骤会自动启动 rabbitmq-server 服务?/p>

 

常用命oQ?/p>

 

rabbitmqctl -h 

rabbitmqctl status 

rabbitmqctl stop

rabbitmqctl start_app

 

 

客户端安装:

maven:

<dependency>

  <groupId>com.rabbitmq</groupId>

  <artifactId>amqp-client</artifactId>

  <version>2.8.4</version>

</dependency>

 

或是下蝲链接Q?/p>

wget http://www.rabbitmq.com/releases/rabbitmq-java-client/v2.8.4/rabbitmq-java-client-bin-2.8.4.tar.gz

 

客户端编?--发送者:

 

package com.jieting.mq.rabbit.send;

import java.io.IOException;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;

public class MessageSend {

    private static final String QUENE_NAME = "hello";

    public static void main(String[] args) throws IOException {

        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("localhost");

        Connection newConnection = connectionFactory.newConnection();
        Channel createChannel = newConnection.createChannel();

        createChannel.queueDeclare(QUENE_NAME, true, false, false, null);
        String message = "hello rabbitmq world!";
        createChannel.basicPublish("", QUENE_NAME, null, message.getBytes());

        System.out.println(" [x] Sent '" + message + "'");

        createChannel.close();
        newConnection.close();

    }
}

 

消费者代码:

 

package com.jieting.mq.rabbit.receive;

import java.io.IOException;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.ConsumerCancelledException;
import com.rabbitmq.client.QueueingConsumer;
import com.rabbitmq.client.ShutdownSignalException;

public class MessageReceive {

    private static final String QUENE_NAME = "hello";

    public static void main(String[] args) throws IOException, ShutdownSignalException, ConsumerCancelledException,
                                          InterruptedException {

        ConnectionFactory connectionFactory = new ConnectionFactory();
        Connection newConnection = connectionFactory.newConnection();
        Channel createChannel = newConnection.createChannel();

        createChannel.queueDeclare(QUENE_NAME, true, false, false, null);
        System.out.println(" [*] Waiting for messages. To exit press CTRL+C");

        QueueingConsumer queueingConsumer = new QueueingConsumer(createChannel);
        createChannel.basicConsume(QUENE_NAME, true, queueingConsumer);
        while (true) {
            QueueingConsumer.Delivery delivery = queueingConsumer.nextDelivery();
            String message = new String(delivery.getBody());
            System.out.println(" [x] Received '" + message + "'");
        }
    }
}

 

以上资料都可?一下地址扑ֈQ?/p>

http://www.rabbitmq.com/java-client.html

http://www.rabbitmq.com/getstarted.html

 



已有 0 人发表留aQ猛?>>q里<<-参与讨论


ITeye推荐





]]>
վ֩ģ壺 þþƷƷް| ޹һaëƬ| caopornѹ| þ޾ƷAB벥| ѿ߿Aվ| һƵ| av벻| Ů18ëƬؼһƵ| Ҹ| ŮԸ߰վ| ޹˾þþƷ99 | þþƷAV鶹| ˳Ƶ| ѹۿ| ޾ƷþþþþͼƬ| ޾ƷAv߹ۿ| ĻӰѹۿ| йƷһëƬѲ| պĻһ| AVƬɫ߹ۿ߳ | AV뾫Ʒɫҹ߹ۿ| պƬӰѹۿ| ѨƬ߹ۿͬѧ| þþƷձҰ| þҹɫƷAV| Ұһ | AŮAVۺϾþþ| ĻѸ| ̱߳ˬƵ99| 13ֽˮ| þþþavרѿ| avֻ߹ۿ| պƷר| òѸԴվ| ԰߹ۿ91| Ļ| ŷձƷ| ޾Ʒ˳߹ۿ| ƷѾƷ| ¹AVר | av˾Ʒ߲|