
ÃÀÍÅÄÚ²¿µÄRPC·þÎñ´ó¶à¹¹½¨ÔÚThriftÖ®ÉÏ£¬ÔÚÈÕ³£¿ª·¢·þÎñµÄ¹ý³ÌÖУ¬ÐèÒªÕë¶ÔÕâЩ·þÎñ½øÐÐѹÁ¦²âÊÔ(ÒÔϼò³ÆÑ¹²â)À´·¢ÏÖDZÔÚÎÊÌâ¡£³£Óõķ½·¨ÓУº
¡ôʹÓÃһЩ½Å±¾ÓïÑÔÈ磺Python¡¢RubyµÈ£¬¶ÁÈ¡ÏßÉÏÈÕÖ¾¹¹½¨ÇëÇó£¬ÓöàÏß³ÌÄ£ÄâÓû§ÇëÇó½øÐÐѹ²â¡£
¡ôʹÓÿªÔ´¹¤¾ß½øÐÐѹ²â¡£ È»¶ø£¬ÎÞÂÛ²ÉÈ¡ÄÄÖÖ·½·¨£¬Ñ¹²â¶¼ÊÇÒ»¸öÊ®·ÖºÄʱ¶øÓÖ·±ËöµÄ¹ý³Ì£¬Ö÷ҪʹµãÓУº
¡ôÐèҪдºÜ¶à´úÂë½âÎöÈÕÖ¾£¬»¹ÔÇëÇ󣬶ÔÓڱȽϸ´ÔÓµÄÇëÇ󣬽âÎöºÜÈÝÒ׳ö´í¡£
¡ôÐèÒª´î½¨½Å±¾»òÕß¹¤¾ßµÄÔËÐл·¾³£¬Í¨³£ÕâÒ»¹ý³Ì±È½ÏºÄʱ¡£
¡ôÓÉÓÚ´òѹ·½·¨Ã»ÓÐͳһ£¬µ¼Ö´òѹµÄ½á¹ûÖ¸±ê±È½Ï»ìÂÒ£¬ÓеĽá¹ûÉõÖÁÒÔÖÕ¶ËÊä³öµÄ·½Ê½Õ¹Ê¾£¬·Ç³£²»Ö±¹Û¡£
¡ô¶ÔÒ»¸öÓ¦ÓõĴòѹ²âÊÔ£¬ÓÉÓÚ»·¾³¡¢´úÂëµÄÎÊÌ⣬µ¼ÖÂ×éÄÚͬѧºÜÄѹ²Ïí¡£
Õë¶ÔÉÏÊöÎÊÌ⣬Ìṩһ¸ö¼òµ¥ºÃÓõÄѹ²â¹¤¾ßÊÇÊ®·ÖÓбØÒªµÄ¡£ ÊÇ·ñÓбØÒªÖظ´ÔìÂÖ×Ó
ÔÚ¹¹½¨Ñ¹²â¹¤¾ß֮ǰ£¬¶ÔÓÚһЩÏÖÓеĿªÔ´¹¤¾ß½øÐÐÁ˵÷ÑС£ÏÖÔÚÖ÷Á÷µÄѹ²â¹¤¾ßÖ÷ÒªÓÐÒÔϼ¸¸ö£º
1.JMeter
JMeterÊÇÒ»¸ö±È½ÏÀÏÅÆµÄѹ²â¹¤¾ß£¬Ö÷ÒªÕë¶ÔHTTP·þÎñ½øÐдòѹ£¬¸Ã¹¤¾ßÔÚÒÔÏ·½Ãæ²¢²»Âú×ãÃÀÍÅÄÚ²¿µÄѹ²âÐèÇó£º
¡ôĬÈϲ»Ö§³ÖThriftµÄ´òѹ²âÊÔ¡£
¡ôÐèÒª±¾µØ°²×°£¬²¢ÇÒÅäÖø´ÔÓ¡£
¡ô¶ÔÓÚÓû§²Ù×÷²¢²»ÓѺÃ

2.twitter/iago
iago ÊÇÒ»¸öÓÉTwitter¿ªÔ´µÄѹ²â¹¤¾ß£¬Ö§³Ö¶ÔHTTP¡¢ThriftµÈ·þÎñ½øÐÐѹ²â£¬ÆäÖ÷ÒªÎÊÌâÈçÏ£º
¡ô¶Ôÿ¸öѹ²âÓ¦Óö¼ÐèÒª´´½¨Ò»¸öÏîÄ¿¡£
¡ôѹ²â½á¹û²¢²»Ö±¹Û¡£
¡ôÁ÷Á¿ÖØ·ÅÒÀÀµ±¾µØÎļþ¡£
¡ôÏîÄ¿ÒÀÀµÓÚÒ»¸ö½ÏÀϰ汾µÄScala£¬´î½¨²»±ã¡£
¡ôÏà¹ØÎĵµ±È½ÏÉÙ¡£
³ý´ËÖ®Í⣬µ±Ê±»¹¿¼²ìÁËGatling¡¢Grinder¡¢LocustµÈһЩ³£¼ûµÄѹ²â¹¤¾ß£¬¶¼ÒòΪÊÊÓó¡¾°ºÍÃÀÍŵÄÐèÇóÓÐЩ³öÈë¶øÅųýÁË¡£
×ÛÉÏ£¬Õë¶Ôµ±Ç°Ñ¹²â¹¤¾ßµÄһЩÏÖ×´£¬¹¹½¨Ò»¸ö¼òµ¥Ò×ÓõÄѹ²â¹¤¾ß»¹ÊǺÜÓбØÒªµÄ¡£
Ä¿±ê
Õë¶Ô֮ǰÌáµ½µÄÍ´µã£¬ÐµÄѹ²â¹¤¾ßÖ÷ÒªÌṩÒÔϹ¦ÄÜ£º
¡ôÏßÉÏÁ÷Á¿¿½±´¡£
¡ô¼òµ¥Ò×ÓõIJÙ×÷½çÃæ(½ÓÈëѹ²âµÄʱ¼äÓ¦¸Ã¿ØÖÆÔÚ1СʱÒÔÄÚ)¡£
¡ôÇåÎúµÄͼ±íÄÜ·´Ó³Ñ¹²âÓ¦Óõĸ÷ÏîÖ¸±ê¡£
¡ôÂú×ã°üÀ¨Thrift¡¢HTTPµÈ·þÎñµÄѹ²âÐèÇó¡£
ÈçºÎ¹¹½¨
³éÏó
Ä¿±êÒѾÃ÷È·£¬ÔõôʵÏÖÄØ£¿Ê×ÏÈÊdzéÏóѹ²âµÄ¹ý³Ì¡£ Ò»¸öµäÐ͵Äѹ²â¹ý³ÌÈçͼËùʾ£¬Ê×ÏÈÔÚinit·½·¨ÀïÃæ£¬½øÐÐһЩ³õʼ»¯µÄ¹¤×÷£¬±ÈÈçÁ¬½ÓÊý¾Ý¿â£¬´´½¨¿Í»§¶ËµÈ¡£½ÓÏÂÀ´£¬ÔÚrun·½·¨ÀïÃæ·¢³öѹ²âÇëÇó£¬ÎªÁ˱£Ö¤Äܹ»¶Ô·þÎñ²úÉú×ã¹»µÄѹÁ¦£¬ÕâÀïͨ³£²ÉÓöàÏ̲߳¢·¢·ÃÎÊ£¬Í¬Ê±¼Ç¼ÿ´ÎÇëÇóµÄ·¢Æðʱ¼äºÍ½áÊøÊ±¼ä£¬ÕâÁ½¸öʱ¼äµÄ¼òµ¥Ïà¼õ¾ÍÄܹ»µÃµ½Ã¿´ÎÇëÇóµÄÏìӦʱ¼ä£¬ÀûÓøýá¹û¾Í¿ÉÒÔ¼ÆËã³öTP90¡¢Æ½¾ùÏìӦʱ¼ä¡¢×î´óÏìӦʱ¼äµÈÖ¸±ê£¬µÈѹ²â½áÊøºó£¬Í¨¹ýdestroy·½·¨½øÐÐ×ÊÔ´»ØÊյȹ¤×÷¡£

ÒÔÉϹý³Ì¿ÉÒÔÓýӿڱíʾ£¬ÎÞÂÛÊÇѹ²âThrift·þÎñ»¹ÊÇHTTP·þÎñ£¬±¾ÖÊÉ϶¼ÊÇÕâÈý¸ö·½·¨ÊµÏֵIJ»Í¬¡£¿¼Âǵ½Ñ¹²â¹¤¾ßµÄÁé»îÐÔºÍͨÓÃÐÔ£¬Ñ¹²â¹¤¾ß¿ÉÒÔ½«Õâ¸ö½Ó¿Ú½»¸ø´òѹ²âÊÔµÄͬѧʵÏÖ£¬¶øÑ¹²â¹¤¾ßÔòÖØµãʵÏÖ¶àÏ̴߳òѹ£¬´òѹ½á¹ûµÄ¾ÛºÏµÈ±È½ÏºÄʱµÄ¹¤×÷¡£
interface Runner { def init(Test app) // ³õʼ»¯Ñ¹²â def run(Test app, String log) // ÿ´Î´òѹÇëÇ󣬴«Èëlog·½±ã¹¹½¨ÇëÇó def destroy(Test app) // ѹ²âÍê±Ïºó£¬»ØÊÕ×ÊÔ´ } |
¿½±´Á÷Á¿
Thrift·þÎñ´òѹµÄÄѵãÖ®Ò»¾ÍÊÇÈçºÎ¼òµ¥µØ¿½±´ÏßÉÏÕæÊµÁ÷Á¿ÓÃÀ´¹¹½¨´òѹÇëÇó¡£Ò»Ð©´óÐ͵ÄThrift·þÎñÊý¾Ý½á¹¹·Ç³£¸´ÔÓ£¬Ð´´òѹ½Å±¾µÄʱºò£¬ÐèÒªºÜ¶à´úÂëÀ´½âÎöÈÕÖ¾£¬¶øÇÒÈÝÒ׳ö´í¡£
Òò´Ë£¬Ìṩһ¸ö¼òµ¥ºÃÓõĿ½±´Á÷Á¿·½·¨ÊÇÊ®·ÖÓбØÒªµÄ¡£
ÔÚÕâÀïѹ²â¹¤¾ßÌṩÁËÒ»¸ö½ÐVCR(¼Ïñ»ú)µÄ¹¤¾ßÀ´¿½±´Á÷Á¿¡£VCRÄܹ»½«ÏßÉϵÄÇëÇóÐòÁл¯ºóдµ½RedisÀïÃæ¡£
¿¼Âǵ½Óû§ÐèÒª²é¿´¾ßÌåÇëÇóºÍÒ×ÓÃÐÔµÈÐèÇó£¬×îÖÕѡȡÁËJSON¸ñʽ×÷ΪÐòÁл¯ºÍ·´ÐòÁл¯µÄÐÒ顣ͬʱ£¬ÐèÒª²¿ÊðÔÚÉú²ú»·¾³£¬ÎªÁ˽µµÍ¶ÔÏßÉÏ·þÎñµÄÓ°Ï죬ÕâÀï²ÉÈ¡Á˵¥Ïß³ÌÒ첽дµÄ·½Ê½À´¿½±´Á÷Á¿¡£
¾ÛºÏÊý¾Ý Ó¦ÓôòѹÍê³Éºó£¬ÐèҪһЩָ±êÀ´ÆÀ¹Àѹ²â½á¹û£¬³£¼ûµÄÖ¸±êÓУº
¡ô×î´óÏìӦʱ¼ä
¡ôƽ¾ùÏìӦʱ¼ä
¡ôQPS
¡ôTP90
¡ôTP50
ѹ²â¹¤¾ß²ÉÓÃÁË InfluxDB À´Íê³ÉÊý¾ÝµÄ¾ÛºÏ¹¤×÷¡£
ÒÔTP90ΪÀý×Ó£¬½öÐèÒªÒ»Ðвéѯ¾ÍÄÜʵÏÖÐèÇó¡£
SELECT PERCENTILE(response_time, 90) FROM test_series GROUP BY time(10s) |
¼Ü¹¹
ÕûÌå¶øÑÔ£¬Õû¸ö´òѹ¹ý³ÌÈçÏ£º

ʵ¼ù
¿½±´Á÷Á¿
ÃÀÍÅÄÚ²¿µÄ·þÎñ´ó¶àʹÓÃJavaÀ´¹¹½¨£¬VCRÒÔMaven PackageµÄ·½Ê½Ìṩ¸øÓû§¡£
¶ÔÓû§À´ËµÖ»ÐèÒª2ÐдúÂë¾Í¿ÉÒÔ¿½±´Á÷Á¿¡£
ΪÁ˲»Ó°ÏìÏßÉÏ·þÎñ£¬Í¨³£Ñ¡È¡µ¥Ì¨»úÆ÷½øÐÐÁ÷Á¿¿½±´¹¤×÷¡£
public class TestAppRPC implements TestApp.Iface { private Vcr _vcr = new Vcr("testapp"); // Ö¸¶¨¿½±´Á÷Á¿µÄkey @Override public TestResponse echo(TestRequest req) throws TException { _vcr.copy(req); // ¿½±´²Ù×÷ long start = System.currentTimeMillis(); TestResponse response = new TestResponse(); return response; } } |
Ò»µ©Á÷Á¿¿½±´Íê³Éºó£¬Í¨¹ýWeb½çÃæ£¬Óû§Äܹ»²é¿´ÈÕÖ¾µÄÊÕ¼¯Çé¿öºÍµ¥ÌõÈÕÖ¾µÄÏêÇé¡£
ѹ²âÂ߼ʵÏÖ
ѹ²â¹¤¾ß²ÉÓÃGroovyÀ´½øÐбàд¡£¶Ôÿ¸öÓ¦ÓÃÀ´Ëµ£¬Ö»ÐèҪʵÏÖrunner½Ó¿Ú¾Í¿ÉÒÔʵÏÖ¶ÔÓ¦ÓõĴòѹ¡£
interface Runner { def init(Test app) def run(Test app, String log) def destroy(Test app) } |
ÒÔThrift·þÎñΪÀý¡£
class TestServiceRunner implements Runner { RPCService.Client _client TTransport _transport; @Override def init(Test app) { def conf = app.config // ¶ÁȡӦÓÃÅäÖà _transport = new TFramedTransport(new TSocket(conf.get("thrift_service_host") as String,
conf.get("thrift_service_port") as int)) TProtocol protocol = new TBinaryProtocol(_transport) _client = new RPCService.Client(protocol) _transport.open() } @Override def run(Test app, String log) { TestRequest req = Vcr.deSerialize(log, TestRequest.class) // ½«¿½±´Á÷Á¿·´ÐòÁл¯ _client.echo(req) // ·¢ËÍÇëÇó } @Override def destroy(Test app) { _transport.close() // ¹Ø±Õ·þÎñ } } |
´´½¨Ó¦ÓÃ
ʵÏÖÒÔÉϽӿں󣬾ͿÉÒÔ¶ÔÓ¦ÓýøÐдòѹÁË¡£
Óû§¿ÉÒÔͨ¹ýWeb½çÃæ´´½¨Ó¦Ó㬳ýÁ˱ØÌîÅäÖÃÒÔÍ⣬Óû§¿ÉÒÔ°´ÕÕÓ¦ÓÃÁé»îÅäÖá£

ÐÔÄÜÖ¸±ê
Óû§¿ÉÒÔͨ¹ýÖ±¹ÛµÄͼ±íÀ´²é¿´Ó¦Óõĸ÷ÖÖÐÔÄÜÖ¸±ê¡£

½áÊøÓï
ѹ²â¹¤¾ßÉÏÏßÒÔÀ´£¬ÒѾ½ÓÈëÁË20¶à¸öÓ¦Óã¬Íê³ÉÊý°Ù´Î´òѹʵÑ飬ÏÖÔÚÓ¦ÓõĽÓÈëʱ¼ä½öÐèÒª15¡«30·ÖÖÓ¡£±£Ö¤ÁËÃÀÍÅ·þÎñµÄÎȶ¨ºÍ½ÚÊ¡ÁË¿ª·¢Í¬Ñ§µÄʱ¼ä£¬Ê¹´ó¼Ò¸æ±ðÁËÒÔÍù·±ËöÈß³¤µÄ´òѹ²âÊÔ¡£
|