ï»??xml version="1.0" encoding="utf-8" standalone="yes"?>午夜精品久久久久,黄页网址在线观看,91精彩在线视频http://www.aygfsteel.com/inter12/zh-cnTue, 03 Jun 2025 05:36:06 GMTTue, 03 Jun 2025 05:36:06 GMT60个äh博客˜qç§»http://www.aygfsteel.com/inter12/archive/2015/03/22/423722.htmlè–›è™næ˜?/dc:creator>è–›è™næ˜?/author>Sun, 22 Mar 2015 08:27:00 GMThttp://www.aygfsteel.com/inter12/archive/2015/03/22/423722.htmlhttp://www.aygfsteel.com/inter12/comments/423722.htmlhttp://www.aygfsteel.com/inter12/archive/2015/03/22/423722.html#Feedback0http://www.aygfsteel.com/inter12/comments/commentRss/423722.htmlhttp://www.aygfsteel.com/inter12/services/trackbacks/423722.html说明blogjava在google引擎中的排名¼‹®å®žéžå¸¸é«˜ï¼Œä¸è¿‡˜q™ä¸ªåšå®¢ä¸­ä¸€äº›æ–‡ç« èµ„料也¼‹®å®žå¾ˆå¥½åQŒæ˜¯ä¸ªäh见过最好的ã€?br />不过自己已经ž®†åšå®¢åœ°å€˜qç§»åˆ°è‡ªå·±æ–°çš„个人地址上了åQ?inter12.org 

]]>
一‹Æ¡çº¿ä¸Šjboss僉|­»é—®é¢˜åˆ†æžhttp://www.aygfsteel.com/inter12/archive/2012/09/17/387938.htmlè–›è™næ˜?/dc:creator>è–›è™næ˜?/author>Mon, 17 Sep 2012 13:09:00 GMThttp://www.aygfsteel.com/inter12/archive/2012/09/17/387938.htmlhttp://www.aygfsteel.com/inter12/comments/387938.htmlhttp://www.aygfsteel.com/inter12/archive/2012/09/17/387938.html#Feedback0http://www.aygfsteel.com/inter12/comments/commentRss/387938.htmlhttp://www.aygfsteel.com/inter12/services/trackbacks/387938.html问题再现åQ?/div>
  个äh中心在上周四上线(2012.9.13)½W¬ä¸€‹Æ¡ä¸Š¾U¿ï¼Œç”׃ºŽ¿Uç§¾~˜ç”±åQŒé—留了部分低çñ”别的BUGåQŒåŽäºŽæ¬¡æ—¥ä¿®å¤ï¼Œä¸‹åˆ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¿ç¨‹çš„答复后åQŒç‘ô¾l­å¾€ä¸‹æ‰§è¡Œï¼Œ˜q›è¡Œ™åµé¢çš„æ¸²æŸ“ã€?/div>
    
    以上都是正常‹¹ç¨‹çš„æµè½¬è¿‡½E‹ï¼Œä½†æ˜¯åQŒè‹¥æˆ‘们其中的一个moduleProcessor抛出异常后,会出çŽîC»€ä¹ˆæƒ…况呢åQŸè¿™ä¸ªå¼‚叿€¼šè¢«æŽ¥å…¥CAT监控的代码会吃掉åQŒå‘Šè¯‰CAT一个日志信息,然后ž®×ƒ»€ä¹ˆéƒ½ä¸åšäº†ã€‚é‚£countDownLatch.countDown();˜q™æ®µä»£ç ž®±æ°¸˜qœä¸ä¼šè¢«æ‰§è¡ŒåQŒè€Œä¸»¾U¿ç¨‹åˆä¾èµ–于子线½E‹é€šè¿‡countDownLatch.countDown();来告知是否执行完了。这个时候就悲剧了,ä¸Èº¿½E‹ä¸€ç›´åœ¨½{‰å¾…子线½E‹çš„æ¶ˆæ¯åQŒæ— æ³•渲染页面返回结果,˜q™ä¸ªæ—¶å€™ç”¨æˆïLš„½W¬ä¸€ååº”会是是不是网¾lœåŽŸå› å¯¼è‡´æ²¡æœ‰åŠ è½½æ•°æ®ï¼Œä¸åœçš„F5åQŒæ¯‹Æ¡éƒ½ä¼šäñ”生一个新的请求进来,若是åˆä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¸­å¿ƒçš„æ‰€æœ‰é¡µé¢éƒ½å¿…须依赖于memberID˜q™ä¸ªå­—段å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为空的情况不会进入后端处理的processoråQŒæ‰€ä»¥åŽç«¯ä¹Ÿž®±æ²¡æœ‰è€ƒè™‘åˆîC»Žcontext获取memberIDä¼šäØ“½Iºï¼Œä½†æ˜¯å®žé™…情况˜q˜æ˜¯å‘生了,˜q™æ®µä»£ç ä¹Ÿåšäº†æ‹¦æˆªï¼Œòq¶æŠ›å‡ÞZº†å¼‚常åQŒä¸˜q?在initMemberInfo˜q™ä¸ªæ–ÒŽ³•的外层,又catch住了˜q™ä¸ªå¼‚常åQ?/div>
try
  ....
   initMemberInfo(context);
   
catch(){
  ....
}
所以说ACTION做的处理òq¶æ²¡æœ‰è“våˆ°æ‹¦æˆªä½œç”¨ï¼Œå¯ÆD‡´˜q™ä¸ª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 catchåQŒæ˜¯è€ƒè™‘åˆ°æˆ‘ä»¬ä¸€äº›åÆˆè¡Œçš„processor存在一些依赖关¾p»ï¼ŒprocessorA出异常的话,processorBž®Þq®—不出问题åQŒä¹Ÿä¸æ¸²æŸ“页面。所以这里就不cacth异常åQŒç”±å…·ä½“çš„processor来决定是否cacth异常。所以在压力‹¹‹è¯•˜q‡ç¨‹åQŒå°±½Ž—其中processor抛出异常åQŒæ¡†æž¶å°±è®¤äØ“˜q™æ˜¯æŸä¸ªä¾èµ–processor抛出的异常,ž®±å°†˜q™ä¸ªå¼‚常抛到WEBåQŒç”±æœ€å¤–层做控åˆÓž¼Œè·Œ™{到统一的错误页面。所以这ä¸Èº¿½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å¼å¤„ç†ï¼Œå¯ÆD‡´½IºæŒ‡é’ˆå¼‚常,同时又没有将˜q™æ®µèŽ·å–æ•°æ®çš„ä»£ç çº³å…¥try中,˜q›ä¸€æ­¥å°†¾pȝ»ŸæŽ¨å‘奔溃边缘ã€?/div>
3.上线前接入CAT代码åQŒæ²¡æœ‰è€ƒè™‘全面åQŒè¿™ŒDµä»£ç åœ¨è‡ªå·±æœ¬åˆ†(记录¾pȝ»Ÿæ‰§è¡Œå¼€é”€åŠå¼‚å¸?外干了不是它的事åQŒcacth住了我们的系¾lŸå¼‚常,˜q™ä¸ªæ‰æ˜¯åŽ‹åž®¾pȝ»Ÿçš„æœ€åŽä¸€æ ¹ç¨»è‰ï¼Œå¯ÆD‡´¾pȝ»Ÿé›ªå´©ã€?/div>
4.框架本èín考虑不够全面åQŒç”¨ä¸€¿Ué æ‰©å±•对自íw«çš„¾U¦æŸæ¥å¤„理异常情况,没有分开的去处理åQšå¤šä¸ªæ— å…³porcessor和多个存在关联processor的两¿Uæƒ…å†üc€?/div>
以上四步åQŒåªè¦ä¸èµ°é”™ä¸€æ­¥ï¼Œž®×ƒ¸ä¼šå‡ºçŽ°å‘¨äº”æ™šä¸Šçš„JBOSS僉|­»é—®é¢˜ã€‚可见一个重大错误大多是ç”׃¸€¾pÕdˆ—的错误连锁导致的ã€?/div>
    
    
   
   
   
  


]]>一‹Æ¡æ€§èƒ½è°ƒä¼˜½W”è®°(¾U¿ç¨‹æ±?http://www.aygfsteel.com/inter12/archive/2012/09/12/387837.htmlè–›è™næ˜?/dc:creator>è–›è™næ˜?/author>Wed, 12 Sep 2012 13:17:00 GMThttp://www.aygfsteel.com/inter12/archive/2012/09/12/387837.htmlhttp://www.aygfsteel.com/inter12/comments/387837.htmlhttp://www.aygfsteel.com/inter12/archive/2012/09/12/387837.html#Feedback0http://www.aygfsteel.com/inter12/comments/commentRss/387837.htmlhttp://www.aygfsteel.com/inter12/services/trackbacks/387837.html普通的性能调优主要从四个方面入æ‰?/p>

¾|‘络åQŒç£ç›˜IOåQŒå†…存,CPU四个斚w¢å…¥æ‰‹åQŒä¸‹é¢æ¡ˆä¾‹å°±æ˜¯ä»Ž˜q™å››ä¸ªè§’度来看ã€?/p>

 

我们的页面每天PVåœ?0W åQŒä¸»è¦æ˜¯åˆ†å¸ƒåœ¨ä¸¤ä¸ªä¸»è¦é¡µé¢ï¼šä¸ªäh主页åQŒå±•½CÞZ¸»™åüc€‚假设每个页面各自承æ‹?0%çš„PVåQŒå‡è®¾è®¿é—®æ—¶é—´é›†ä¸­åœ¨ç™½å¤©8ž®æ—¶åQŒåã^均下来每¿U’çš„è¯äh±‚数是 5.2个,考虑到高峰情况,那么我们ž®×ƒ¹˜ä»¥ç³»æ•?0, ž®±å½“100个处理,我们最大的一个请求会产生13个processor ,也就是说 最大äñ”生的¾U¿ç¨‹å›žäº‹ 13*100 = 1300。也ž®±æ˜¯è¯´é«˜å³°æ—¶åˆÖM¼šæœ?300个线½E‹éœ€è¦è¢«å¤„理åQŒæˆ‘们将队列讄¡½®ä¸?000åQŒå¯¹äºŽé«˜å³°æƒ…况就抛弃å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>

 

15¾U¿ç¨‹Â 

循环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>

inåQšæ¯¿U’èÊY中断‹Æ¡æ•°

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
  

å…Ïx³¨soft ˜q™ä¸ªå‚æ•° ˜q™ä¸ªä»£è¡¨å½“前CPU在所有时间中åQŒç”¨äºŽåˆ‡æ¢ä¸Šä¸‹æ‰€åŒ–时间比,若是èŠÞp´¹çš„越多,代表当前的线½E‹åˆ‡æ¢è¿‡äºŽé¢‘¾Jï¼Œæ²¡æœ‰å……分利用CPUåQŒå¾è®®å‡ž®‘线½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™ä¸ªæ•°æ®ä¸Šçœ‹å‡ºå…¶ä¸­ä¸€ä¸ªCPUèŠÞp´¹åœ¨åˆ‡æ¢çš„æ—‰™—´æ¯”是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‹æ•°å¢žåŠ åˆîCº†236åQŒä¹Ÿž®±æ˜¯è¯´å¢žåŠ äº†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ŒåŽ‹‹¹‹æœŸé—ß_¼Œygc˜q˜æ˜¯è›®é¢‘¾Jï¼Œä½†æ˜¯æ¯æ¬¡ygc后进入old区的数据òq¶ä¸æ˜¯å¾ˆå¤šï¼Œè¯´æ˜Žæˆ‘们的应用大部分是朝生夕死,òq¶ä¸ä¼šå‘生频¾Jfgc的情况,之后ž®×ƒ¸ç”¨æŠŠé‡å¿ƒæ”‘Öœ¨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Œä½†æ˜¯æœ€åŽçœ‹åˆ°çš„æ¶ˆè€—时间是557msåQŒä¸”上面的情况说明了åQŒå­˜åœ¨å¤§é‡é˜Ÿåˆ—积压,我们的数据处理processor都在½{‰å¾…队列äº?/p>

 

下面是我们通过

Avg(ms):

½W¬ä¸€‹Æ¡ï¼š 662.5 毫秒

½W¬äºŒ‹Æ¡ï¼š 680   毫秒

½W¬ä¸‰‹Æ¡ï¼š 690   毫秒

 

通过上面的分析,òq›_‡å“åº”æ—‰™—´æ˜¯ï¼š680ms,基本可以¼‹®å®šé—®é¢˜åœ¨äºŽ¾U¿ç¨‹æ± corePoolSize˜q‡å°,坯D‡´äº†ä¸€å®šçš„æ•°æ®åœ¨é˜Ÿåˆ—中¿U¯åŽ‹ã€?/p>

 

 

---------------------------------------------  ˜q™æ˜¯ä¸€æ¡ä¼Ÿå¤§çš„分割¾U? ---------------------------------------------

‹¹‹è¯•案例二:

 

改动åQšå¢žåŠ ä¸€å€çš„corePoolSize

 

15¾U¿ç¨‹Â 

循环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	
 

 

初始情况CPU˜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)

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™ä¸ªjava¾U¿ç¨‹æ•°çš„变化情况å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çš„æ¯”ä¾‹ç¡®å¤§å¤§å¢žåŠ äº†ã€‚å•æ æ€¸­æ–­æœ€é«˜è¾¾åˆîCº†7.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å’ŒmaxSize坯D‡´æ€§èƒ½å˜æ…¢äº†ã€‚慢了近80毫秒。说明过多的CPUòq¶ä¸ä¼šåŠ å¿«æˆ‘ä»¬çš„å¤„ç†é€Ÿåº¦ã€?/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˜æ˜¯å¾ˆåŽ‰å®Ÿë€‚è¾¾åˆîCº†8.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¯”è¾?coreåQ? 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

中断旉™—´¼‹®å®žä»?%下降åˆîCº†4%左右ã€?/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“论åQŒJVM的垃圑֛žæ”Óž¼Œæœ¬åœ°¼‚ç›˜IOåQŒæ“ä½œç³»¾lŸå†…存都不会å¯ÒŽœ¬åº”用产生影响åQŒå”¯ä¸€çš„元素就是线½E‹æ± å¤§å°çš„设¾|®ã€?span style="color: #ff0000;">目前‹¹‹è¯•出来的最佳策略是åQ?/span>

corePoolSize = cpu + 1

maxPoolSize = 2 *  cpu   

 



已有 0 人发表留­a€åQŒçŒ›å‡?>>˜q™é‡Œ<<-参与讨论


ITeye推荐





]]>
AOP 的简单入é—?/title><link>http://www.aygfsteel.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://www.aygfsteel.com/inter12/archive/2012/09/08/387838.html</guid><wfw:comment>http://www.aygfsteel.com/inter12/comments/387838.html</wfw:comment><comments>http://www.aygfsteel.com/inter12/archive/2012/09/08/387838.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/inter12/comments/commentRss/387838.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.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çš„AOPåQŒä¹Ÿè°ˆè°ˆè‡ªå·±å¯¹äºŽ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Œä¼´éšè¿™äº›ä¸œè¥¿çš„都会有相应体¾pÕd†…的术语ã€?/p> <p>我个人的看法是一切术语的出现不是òq¶ä¸æ˜¯å‘大众解释清楚˜q™äšg事到底是怎么一回事åQŒå…¶ä¸»è¦æ˜¯åŸºäºŽä¸¤ä¸ªæ–¹é¢è€ƒè™‘åQ?/p> <p> </p> <p>1.è®©è‡ªå·±æå‡ø™§‚ç‚ÒŽ˜¾å¾—ç³»¾lŸåŒ–åQŒæ›´å…ähœ‰è¯´æœåŠ›ã€?/p> <p>2.˜qähƒ‘大众åQŒæˆ–是迷¾pŠé‚£äº›åˆš˜q›å…¥˜q™ä¸ªé¢†åŸŸçš„初学者ã€?/p> <p> </p> <p>ä¸¤ä¸ªçœ‹ä¼¼çŸ›ç›¾çš„å› ç´ ï¼Œå…¶å®žå½’ç»“åˆ°æœ¬è´¨å°±æ˜¯å°†ä¸€ä¸ªç®€å•çš„ä¸œè¥¿å¤æ‚åŒ–åÆˆ˜qïL³Šé‚£äº›è¾¨åˆ«èƒ½åŠ›çš„ä¸€èˆ¬çš„äººï¼Œå¤§å®¶å¯¹äºŽæŠ½è±¡åˆîC¸€å®šç¨‹åº¦çš„东西但是心怀敬畏之心的,然后带着膜拜的心理去接受åQŒç”Ÿæ€•一不小心亵渎了内心的女¼œžã€‚扯开来讲现在½C¾ä¼šåQŒå®˜å‘˜çš„道å¯d沦ä“áåQŒå…¶ä¸­çš„一个诱因就是对于敬畏之心的¾~ºå¤±åQŒå½“一个äh无所畏时åQŒæ‰æ˜¯æœ€å¯æ€•çš„åQŒå› ä¸ø™¿™ä¸ªæ—¶å€™å·²¾læ²¡æœ‰ä“Q何约束能¾U¦æŸä»–çš„è¡ŒäØ“ã€?/p> <p> </p> <p>回归正题åQŒæ—¢ç„¶æåˆ°æœ¯è¯­ï¼Œé‚£ä¹ˆæˆ‘们ž®±å°†AOP中的那些术语列出来看看ã€?/p> <p>切面åQˆAspectåQ‰ã€è¿žæŽ¥ç‚¹åQˆJoinpointåQ‰ã€é€šçŸ¥åQˆAdviceåQ‰ã€åˆ‡å…¥ç‚¹åQˆPointcutåQ?、目标对象(Target ObjectåQ‰ã€AOP代理åQˆAOP ProxyåQ‰ã€?/p> <p>通知又分为几¿Uï¼šå‰ç½®é€šçŸ¥åQˆBefore adviceåQ‰ã€åŽé€šçŸ¥åQˆAfter adviceåQ‰ã€è¿”回后通知åQˆAfter return adviceåQ‰ã€çޝ¾l•通知åQˆAround adviceåQ‰ã€æŠ›å‡ºå¼‚常后通知åQˆAfter throwing adviceåQ?½{‰ã€?/p> <p> </p> <p>好了åQŒçŽ°åœ¨æˆ‘ä»¬æ¥çœ‹çœ‹˜q™äº›æœ¯è¯­åQŒè°èƒ½ä¸€çœ¼å°±æ˜Žç™½˜q™äº›ä¸œè¥¿èƒ½å‘Šè¯‰æˆ‘们什么?谁能通畅的理清楚它们之间的关¾p…R€‚开始解释之前,我们看看¾l´åŸºç™„¡§‘上对AOP的定义是什么:</p> <p> </p> <pre class="java" name="code">面向侧面的程序设计(aspect-oriented programmingåQŒAOPåQŒåˆè¯‘作面向斚w¢çš„程序设计、觀點導向編½E‹ï¼‰æ˜¯è®¡½Ž—机¿U‘学中的一个术语,指一¿Uç¨‹åºè®¾è®¡èŒƒåž‹ã€‚该范型以一¿Uç§°ä¸ÞZ¾§é¢ï¼ˆaspectåQŒåˆè¯‘作斚w¢åQ‰çš„è¯­è¨€æž„é€ äØ“åŸºç¡€åQŒä¾§é¢æ˜¯ä¸€¿Uæ–°çš„æ¨¡å—化机制åQŒç”¨æ¥æ˜q°åˆ†æ•£åœ¨å¯¹è±¡ã€ç±»æˆ–函æ•îC¸­çš„æ¨ªåˆ‡å…³æ³¨ç‚¹åQˆcrosscutting concernåQ‰ã€?/pre>   <p> </p> <p>多么½Ž€å•的解释åQŒå°±æ˜¯å¯¹äºŽé‚£äº›åœ¨ä¸È¨‹åºä¸šåŠ¡ä¹‹å¤–çš„äº‹æƒ…åQŒæˆ‘们该怎么设计åQŒçœ‹æ¸…楚åQŒæ˜¯½E‹åºè®¾è®¡åQŒè€Œä¸æ˜¯ç¨‹åºç¼–码,很多地方都将AOP理解成面向切面的¾~–码åQŒé‚£æ˜¯é”™è¯¯ï¼ŒAOP¾U¦å®šçš„æ˜¯ä¸€¿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Œè¿˜æ˜¯è¿œ¼›ÖMº›åQŒå› ä¸ÞZ»–们不是基于大量的兯‚±¡åŽï¼Œ˜q›è¡ŒæŠ½è±¡åQŒä»–们不˜q‡æ˜¯é‚¯éƒ¸å­¦æ­¥çš„æŠ„袭那些真正的架构师的æƒÏx³•åQŒåÆˆè½¬å˜ä¸ø™‡ªå·Þqš„观点åQŒTMDž®±æ˜¯ä¸ªå¤§å¿½æ‚ )</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Œå¯OOXXåQŒç¡¬¾~–码的方式就是:</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状态中..... 很highåQŒå¾ˆ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>好了åQŒAOP的就是个˜q™ä¹ˆ½Ž€å•的东西åQŒåˆ«åŽÀLƒ³é‚£äº›¾Jæ‚çš„spring配置和概忉|œ¯è¯­ã€‚它只是一¿Uè®¾è®¡èŒƒåž‹ã€?/p> <p> </p> <p> </p> <p>¾l•了˜q™ä¹ˆä¹…,让我们来打倒那些纸老虎吧ã€?/p> <p>我开饭店åQŒå±Œä¸ã€é™¢é•¿æ¥åƒé¥­åQŒç¾Žå¥³ä»¬æ‹›å¾…™å‘Ö®¢ åQŒè¿™ä¸ªæ˜¯æˆ‘们的主业ã€? ========  目标对象åQˆTarget ObjectåQ?ž®±æ˜¯åº—主我,我开了两个店åQŒæˆé™¢å’Œé¥­åº—</p> <p>哦,北大院长来饭店吃饭了                                                            ========  切入点(PointcutåQ?他们来我戏院看戏的话åQŒä¸½Ž¡ï¼Œç›´ç®¡é¥­åº—的事</p> <p>院长开始吃饭,喝酒了ã€?                                                              ========  ˜qžæŽ¥ç‚¹ï¼ˆJoinpointåQ?åQŒå°±æ˜¯æˆ‘们的一些行为,院长如果来围观的话,无视之,哥是开饭店的ã€?/p> <p>院长惌™·Ÿ¾ŸŽå¥³ä»¬OOXXäº?                                                              ========  通知åQˆAdviceåQ‰é™¢é•¿æ¥äº†ï¼Œä¹Ÿåƒäº†é¥­äº†ï¼Œé‚£æŽ¥ä¸‹æ¥òq²ä»€ä¹ˆå‘¢åQŸé€šçŸ¥ž®±æ˜¯å†›_®šòq²ä»€ä¹?OOXX或是‹z—脚</p> <p>院长除了想OOXX之外åQŒè¿˜æƒÏx´—脚,那么怎么办呢åQ?                          ========  切面åQˆAspectåQ?åQŒè§„定院长来了可以干什么,ž®±æ˜¯å†›_®šå¯ä»¥æœ‰å¤šž®‘个通知åQšOOXX||‹z—脚 或是 OOXX && ‹z—脚</p> <p>----------------------------------------------------------------------------------------------------</p> <p>院长惛_ƒé¥­åŽ‹z—脚                                                                ======== 后通知åQˆAfter adviceåQ‰Â?/p> <p>院长惛_ƒé¥­å‰‹z—脚                                                                ======== 前置通知åQˆBefore adviceåQ?/p> <p>院长æƒÏx ¹æ®åƒé¥­åŽçš„心情决定是OOXX˜q˜æ˜¯‹z—脚                         ======== ˜q”回后通知åQˆAfter return adviceåQ?/p> <p>院长吃饭吃出脑中风了                                                          ======== 抛出异常后通知åQˆAfter throwing adviceåQ‰è¿™ä¸ªæ—¶å€™æœ‰ä¸ªé€šçŸ¥è·›_‡ºæ¥ï¼šæ‰?20åQŒé€åŒ»é™¢ï¼</p> <p>院长想饭前洗脚,饭后OOXX                                                 ======== 环绕通知åQˆAround adviceåQ?/p> <p> </p> <p>ä½œäØ“è€æ¿çš„æˆ‘åQŒåº”该怎么更好的切入这些洗脚啊åQŒOOXX服务å‘?   ======== AOP代理åQˆAOP ProxyåQ‰æ€Žä¹ˆåœ¨å¹²å¥½æ‹›å¾…顾客这件事上切å…?‹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"); } } 配置文äšgåQ? <?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> 人发表留­a€åQŒçŒ›å‡?>><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://www.aygfsteel.com/inter12/aggbug/387838.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/inter12/" target="_blank">è–›è™næ˜?/a> 2012-09-08 18:01 <a href="http://www.aygfsteel.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://www.aygfsteel.com/inter12/archive/2012/07/26/387839.htmlè–›è™næ˜?/dc:creator>è–›è™næ˜?/author>Thu, 26 Jul 2012 07:01:00 GMThttp://www.aygfsteel.com/inter12/archive/2012/07/26/387839.htmlhttp://www.aygfsteel.com/inter12/comments/387839.htmlhttp://www.aygfsteel.com/inter12/archive/2012/07/26/387839.html#Feedback0http://www.aygfsteel.com/inter12/comments/commentRss/387839.htmlhttp://www.aygfsteel.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šæ·»åŠ æ‰§è¡Œåˆ†æ•°çš„valueåQ?score必须是double¾cÕdž‹çš„æ•°å€?/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

语法åQšZCARD 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

语法åQšZSCORE 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

语法åQšZINCRBY key score value 

释义åQšå¯¹äºŽæŒ‡å®šçš„value˜q›è¡ŒåŠ æ³•æ“ä½œ

实践å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

语法åQšZRANGE|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

语法åQšZRANGEBYSCORE 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

语法åQšzrank|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

语法åQšZINTERSTORE 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

语法åQšZUNIONSTORE destination numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE SUM|MIN|MAX]

释义åQšè®¡½Ž—给定的一个或多个有序集的òq‰™›†åQŒå…¶ä¸­ç»™å®?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 人发表留­a€åQŒçŒ›å‡?>>˜q™é‡Œ<<-参与讨论


ITeye推荐





]]>
redis 学习½W”è®°3--sethttp://www.aygfsteel.com/inter12/archive/2012/07/25/387840.htmlè–›è™næ˜?/dc:creator>è–›è™næ˜?/author>Wed, 25 Jul 2012 10:36:00 GMThttp://www.aygfsteel.com/inter12/archive/2012/07/25/387840.htmlhttp://www.aygfsteel.com/inter12/comments/387840.htmlhttp://www.aygfsteel.com/inter12/archive/2012/07/25/387840.html#Feedback0http://www.aygfsteel.com/inter12/comments/commentRss/387840.htmlhttp://www.aygfsteel.com/inter12/services/trackbacks/387840.html 

redis学习½W”è®°3--set

 

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

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

sortSetåQšæœ‰åºï¼Œä¸èƒ½é‡å¤çš„é›†åˆÂ?/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 删除元素

语法åQšsrem 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 列出所有信æ?¾cÖM¼¼listçš?lrange

语法åQšsmembers key 

实践åQ?/p>

redis 127.0.0.1:6379> smembers s1 

1) "2"

redis 127.0.0.1:6379> 

 

 

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

语法åQšsismember 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

语法åQšscard key 

实践åQ?/p>

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

(integer) 2

redis 127.0.0.1:6379> 

 

6.SMOVE ž®†é›†åˆä¸­ä¸€ä¸ªå…ƒç´ è{¿UÕdˆ°å¦ä¸€ä¸ªé›†åˆä¸­

语法: 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中的1¿UÕdЍåˆîCº†S2ä¸?/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 取两个集合的交集

语法åQšSINTER 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¶ä¿å­˜åˆ°å¦ä¸€ä¸ªé›†åˆä¸­Â 

语法åQšSINTERSTORE 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‰™›†Â 

语法åQšSUNION 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 取两个集合的òq‰™›†òq¶ä¿å­˜åˆ°å¦ä¸€ä¸ªé›†åˆä¸­Â 

语法: 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 取两个集合的差集

语法åQšSDIFF 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 人发表留­a€åQŒçŒ›å‡?>>˜q™é‡Œ<<-参与讨论


ITeye推荐





]]>
redis 学习½W”è®°2--Listhttp://www.aygfsteel.com/inter12/archive/2012/07/25/387841.htmlè–›è™næ˜?/dc:creator>è–›è™næ˜?/author>Wed, 25 Jul 2012 08:15:00 GMThttp://www.aygfsteel.com/inter12/archive/2012/07/25/387841.htmlhttp://www.aygfsteel.com/inter12/comments/387841.htmlhttp://www.aygfsteel.com/inter12/archive/2012/07/25/387841.html#Feedback0http://www.aygfsteel.com/inter12/comments/commentRss/387841.htmlhttp://www.aygfsteel.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 命ä×oé˜Õd¡žåQŒç›´åˆ°ç­‰å¾…è¶…æ—¶æˆ–å‘çŽ°å¯å¼¹å‡ºå…ƒç´ äØ“æ­¢ã€?/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

语法åQšLREM 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      // 已经被清½IÞZº†ã€?/p>

(empty list or set)

redis 127.0.0.1:6379> 

 

3.LSET

语法åQšLSET 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

语法åQšLTRIM 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

语法åQšLINDEX key index

释义åQšè¿”回列è¡?key 中,下标ä¸?index 的元素ã€?/p>

 下标(index)参数 start å’?stop 都以 0 为底åQŒä¹Ÿž®±æ˜¯è¯ß_¼Œä»?0 表示列表的第一个元素,ä»?1 表示列表的第二个元素åQŒä»¥æ­¤ç±»æŽ¨ã€?/p>

 你也可以使用负数下标åQŒä»¥ -1 表示列表的最后一个元素, -2 表示列表的倒数½W¬äºŒä¸ªå…ƒç´ ï¼Œä»¥æ­¤¾cÀLލã€?/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  ¾cÖM¼¼äºŽLSET,一个是æ ÒŽ®ä¸‹æ ‡æ¥æ’入,一个是æ ÒŽ®pivot来插入数据ã€?/p>

语法åQšLINSERT key BEFORE|AFTER pivot value

释义åQšå°†å€?value 插入到列è¡?key 当中åQŒä½äºŽå€?pivot 之前或之后ã€?/p>

  å½?pivot 不存在于列表 key æ—Óž¼Œä¸æ‰§è¡Œä“Q何操作ã€?/p>

  å½?key 不存在时åQ?key 被视为空列表åQŒä¸æ‰§è¡Œä»ÖM½•操作ã€?/p>

  如果 key 不是列表¾cÕdž‹åQŒè¿”回一个错误ã€?/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 

语法åQšRPOPLPUSH 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     //ž®†l1ž®ùNƒ¨çš„æ•°æ®å¼¹å‡ø™¿›å…¥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 

语法åQšBRPOPLPUSH source destination timeout

释义åQšBRPOPLPUSH æ˜?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 

 

在另一个客æˆïL«¯æ·ÕdŠ æ•°æ®åŽï¼Œž®Þp{¿UÖMº†æ•°æ®

 

 

 



已有 0 人发表留­a€åQŒçŒ›å‡?>>˜q™é‡Œ<<-参与讨论


ITeye推荐





]]>
redis学习½W”è®°1--stringhttp://www.aygfsteel.com/inter12/archive/2012/07/24/387842.htmlè–›è™næ˜?/dc:creator>è–›è™næ˜?/author>Tue, 24 Jul 2012 09:29:00 GMThttp://www.aygfsteel.com/inter12/archive/2012/07/24/387842.htmlhttp://www.aygfsteel.com/inter12/comments/387842.htmlhttp://www.aygfsteel.com/inter12/archive/2012/07/24/387842.html#Feedback0http://www.aygfsteel.com/inter12/comments/commentRss/387842.htmlhttp://www.aygfsteel.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:代表正确 0åQšä»£è¡¨é”™è¯?/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çš„valueåQŒåƈ获取讄¡½®å‰çš„å€?。相当于重置功能ã€?/p>

 

 

实践åQ?/p>

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

redis 127.0.0.1:6379> incrby count 10 

(integer) 10

redis 127.0.0.1:6379> getset count "5"    // ˜q™ä¸ªæ—¶å€™è¿”回的æ˜?0åQŒä¸æ˜?

"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 ¾cÖM¼¼äºŽ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½åŠ æ•°æ® åQŒsetrange是截取字½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¦ä¸²¾cÕdž‹åˆ™æŠ¥é”™ã€?/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 åQŒDECRBY

 

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‡æœŸæ—‰™—´ä¸?0¿U?/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 人发表留­a€åQŒçŒ›å‡?>>˜q™é‡Œ<<-参与讨论


ITeye推荐





]]>
redis 安装½W”è®°http://www.aygfsteel.com/inter12/archive/2012/07/24/387843.htmlè–›è™næ˜?/dc:creator>è–›è™næ˜?/author>Tue, 24 Jul 2012 09:26:00 GMThttp://www.aygfsteel.com/inter12/archive/2012/07/24/387843.htmlhttp://www.aygfsteel.com/inter12/comments/387843.htmlhttp://www.aygfsteel.com/inter12/archive/2012/07/24/387843.html#Feedback0http://www.aygfsteel.com/inter12/comments/commentRss/387843.htmlhttp://www.aygfsteel.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>

 

基本常用命ä×oåQ?/p>

redis-server åQšè¿è¡Œä¸€ä¸ªredisserver

redis-cli :redis命ä×o行版本的客户端,同本地或是远½E‹redis服务˜q›è¡Œäº¤äº’

redis-benchmark : ‹‚€æŸ¥redis服务性能的命ä»?/p>

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

 

若是在make的时候没有将redis-serveråQŒredis-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˜æœ‰æ‰€æœ‰å¯ç”¨å®¢æˆïL«¯åQ?/p>

http://redis.io/clients

 

5.redis的持久化

å› äØ“æ˜¯å†…å­˜åž‹çš„NOSQLåQŒæœ‰ä¸¤ç§æ–¹å¼ã€?.使用save命ä×oåQŒä¼šž®†æ•°æ®åˆ·æ–°åˆ°æ–‡äš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_6379˜q™ä¸ªè„šæœ¬ã€?/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 人发表留­a€åQŒçŒ›å‡?>>˜q™é‡Œ<<-参与讨论


ITeye推荐






]]>
AMQP--rabbitmq--1http://www.aygfsteel.com/inter12/archive/2012/07/17/387844.htmlè–›è™næ˜?/dc:creator>è–›è™næ˜?/author>Tue, 17 Jul 2012 09:39:00 GMThttp://www.aygfsteel.com/inter12/archive/2012/07/17/387844.htmlhttp://www.aygfsteel.com/inter12/comments/387844.htmlhttp://www.aygfsteel.com/inter12/archive/2012/07/17/387844.html#Feedback0http://www.aygfsteel.com/inter12/comments/commentRss/387844.htmlhttp://www.aygfsteel.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>

 

常用命ä×oåQ?/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 人发表留­a€åQŒçŒ›å‡?>>˜q™é‡Œ<<-参与讨论


ITeye推荐





]]>
Ö÷Õ¾Ö©Öë³ØÄ£°å£º ÁÙÎäÏØ| ¹óÖÝÊ¡| ÉÇÍ·ÊÐ| º×·åÏØ| ±¦¼¦ÊÐ| ÔÆ¸¡ÊÐ| ¿¦Ê²ÊÐ| Óå±±Çø| ÊÙÑôÏØ| ïö¹éÏØ| ÎôÑôÏØ| ÁÙÏæÊÐ| ¶î¼ÃÄÉÆì| È«½·ÏØ| µ±ÐÛÏØ| ϼÆÖÏØ| ÓíÖÝÊÐ| ·ï¸ÔÏØ| ÀäË®½­ÊÐ| ÇúÖÜÏØ| ͬ½­ÊÐ| ·áÔ­ÊÐ| ¬ÊÏÏØ| ·Ê¶«ÏØ| ¹ãÁéÏØ| ¼¯ÏÍÏØ| ·±ÖÅÏØ| ÓÀ¾¸ÏØ| ÈýÃÅÏ¿ÊÐ| вýÏØ| ¶¨Ô¶ÏØ| ¿µÂíÏØ| ²ÔÉ½ÏØ| ãÉÐÐÇø| ãþ´¨ÏØ| äųØÏØ| ÀÖɽÊÐ| ÇåÁ÷ÏØ| ²ý½­| Í©°ØÏØ| ºé½­ÊÐ|