2017-06-20 29 views
0

嘗試使用Redis模擬重負載情況(僅限默認配置)。 爲了簡單起見,當立即執行multi時,關閉連接。爲連接到Redis的大量Vertx引發的異常

import io.vertx.core.*; 
    import io.vertx.core.json.Json; 
    import io.vertx.redis.RedisClient; 
    import io.vertx.redis.RedisOptions; 
    import io.vertx.redis.RedisTransaction; 


    class MyVerticle extends AbstractVerticle { 
     private int index; 

     public MyVerticle(int index) { 
      this.index = index; 
     } 

     private void run2() { 
      RedisClient client = RedisClient.create(vertx, new RedisOptions().setHost("127.0.0.1")); 
      RedisTransaction tr = client.transaction(); 

      tr.multi(ev2 -> { 
       if (ev2.succeeded()) { 
       tr.exec(ev3 -> { 
        if (ev3.succeeded()) { 
         tr.close(i -> { 
          if (i.failed()) { 
           System.out.println("FAIL TR CLOSE"); 
           client.close(j -> { 
            if (j.failed()) { 
             System.out.println("FAIL CLOSE"); 
            } 
           }); 
          } 
         }); 
        } 
        else { 
         System.out.println("FAIL EXEC"); 
         tr.close(i -> { 
          if (i.failed()) { 
           System.out.println("FAIL TR CLOSE"); 
           client.close(j -> { 
            if (j.failed()) { 
             System.out.println("FAIL CLOSE"); 
            } 
           }); 
          } 
         }); 
        } 
       }); 
       } 
       else { 
        System.out.println("FAIL MULTI"); 
        tr.close(i -> { 
         if (i.failed()) { 
          client.close(j -> { 
           if (j.failed()) { 
            System.out.println("FAIL CLOSE"); 
           } 
          }); 
         } 
        }); 
       } 
      }); 
     } 

     @Override 
     public void start(Future<Void> startFuture) { 
      long timerID = vertx.setPeriodic(1, new Handler<Long>() { 
       public void handle(Long aLong) { 
        run2(); 
       } 
      }); 
     } 

     @Override 
     public void stop(Future stopFuture) throws Exception { 
      System.out.println("MyVerticle stopped!"); 
     } 

    } 

    public class Periodic { 
     public static void main(String[] args) { 
      Vertx vertx = Vertx.vertx(); 

      for (int i = 0; i < 8000; i++) { 
       vertx.deployVerticle(new MyVerticle(i)); 
      } 
     } 
    } 

儘管連接已正確關閉,但仍然出現警告錯誤。 甚至在我把更多的邏輯放在多個之前,它們都被拋出。

2017-06-20 16:29:49 WARNING io.netty.util.concurrent.DefaultPromise notifyListener0 An exception was thrown by io.vertx.core.net.impl.ChannelProvider$$Lambda$61/1899599620.operationComplete() 
    java.lang.IllegalStateException: Uh oh! Event loop context executing with wrong thread! Expected null got Thread[globalEventExecutor-1-2,5,main]  
    at io.vertx.core.impl.ContextImpl.lambda$wrapTask$2(ContextImpl.java:316) 
    at io.vertx.core.impl.ContextImpl.executeFromIO(ContextImpl.java:193) 
    at io.vertx.core.net.impl.NetClientImpl.failed(NetClientImpl.java:258) 
    at io.vertx.core.net.impl.NetClientImpl.lambda$connect$5(NetClientImpl.java:233) 
    at io.vertx.core.net.impl.ChannelProvider.lambda$connect$0(ChannelProvider.java:42) 
    at io.netty.util.concurrent.DefaultPromise.notifyListener0(DefaultPromise.java:507) 
    at io.netty.util.concurrent.DefaultPromise.notifyListenersNow(DefaultPromise.java:481) 
    at io.netty.util.concurrent.DefaultPromise.access$000(DefaultPromise.java:34) 
    at io.netty.util.concurrent.DefaultPromise$1.run(DefaultPromise.java:431) 
    at io.netty.util.concurrent.GlobalEventExecutor$TaskRunner.run(GlobalEventExecutor.java:233) 
    at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:144) 
    at java.lang.Thread.run(Thread.java:745) 

是否有這個錯誤的原因?

+0

爲什麼你創造8000個垂直軸? – tsegismont

+0

來模擬併發請求/事務(在prod中,我們可能會以2000結束)。不管數量多少,錯誤都不應該發生,對吧? – user5733033

+0

即使有500個垂直軸,頻率爲100ms,我們仍然會得到錯誤。 – user5733033

回答

0

你會繼續得到錯誤,因爲你測試了錯誤的東西。

首先,頂點不是胖協程。他們是薄弱的演員。意義創造500個不會加快速度,但可能會放慢速度,因爲事件循環仍然需要在它們之間切換。其次,如果您想準備2K併發請求,請將Vertx應用程序放在一臺計算機上,然後在網絡上運行wrk或類似的工具。

三,你的Redis也在同一臺機器上。我希望在您的製作中不會出現這種情況,因爲Redis將通過CPU與Vertx競爭。

一旦設置正確,我相信你將能夠很容易地處理10K請求。我已經看到Vertx使用PostgreSQL處理適度機器上的8K請求。