±à¼ÍƼö: |
±¾ÎÄÀ´×ÔÓÚÈîÒ»·å,ÎÄÕÂÖ÷Òª½²½âÁ˹¹½¨µÄÁ÷³Ì£¬Ã¿¸ö²½Öè½éÉܵĽÏΪÏêϸ£¬Ï£Íû¶Ô´ó¼ÒÓаïÖú¡£ |
|
Èí¼þºÜÉÙ(Èç¹ûÓеϰ)´æÔÚÓÚÐÅÏ¢Õæ¿ÕÖС£ÖÁÉÙ£¬ÕâÊÇÎÒÃÇÈí¼þ¹¤³Ìʦ¿ÉÒÔΪÎÒÃÇ¿ª·¢µÄ´ó¶àÊýÓ¦ÓóÌÐò×ö³öµÄ¼ÙÉè¡£
ÔÚÈκιæÄ£ÉÏ£¬Ã¿ÖÖÈí¼þ¶¼ÒÔijÖÖ·½Ê½ÓëÆäËûÈí¼þ½øÐÐͨÐÅ£¬³öÓÚ¸÷ÖÖÔÒò£º´Óij´¦»ñÈ¡²Î¿¼Êý¾Ý£¬·¢ËÍ¼à¿ØÐźţ¬ÓëÆäËû·þÎñ±£³ÖÁªÏµ£¬Í¬Ê±×÷Ϊ·Ö²¼Ê½µÄÒ»²¿·ÖϵͳµÈµÈ¡£

¼ò»¯Èí¼þ¼¯³É£ºÒ»¸öApache Camel½Ì³Ì
ÔÚ±¾½Ì³ÌÖУ¬Äú½«Á˽⼯³É´óÐÍÈí¼þµÄһЩ×î´óÌôÕ½£¬ÒÔ¼°Apache CamelÈçºÎÇáËɽâ¾öÕâЩÄÑÌâ¡£
ÎÊÌ⣺ϵͳ¼¯³ÉµÄÌåϵ½á¹¹Éè¼Æ
ÔÚÄúµÄÈí¼þ¹¤³ÌÖУ¬Äú¿ÉÄÜÖÁÉÙ×öÁËÒ»´ÎÒÔϲÙ×÷£º
1.È·¶¨Ó¦Æô¶¯Êý¾Ý·¢Ë͵ÄÒµÎñÂ߼Ƭ¶Î¡£
2.ÔÚÏàͬµÄÓ¦ÓóÌÐò²ã£¬¸ù¾ÝÊÕ¼þÈËµÄÆÚÍûдÈëÊý¾Ýת»»¡£
3.½«Êý¾Ý·â×°ÔÚÊʺÏͨ¹ýÍøÂç´«ÊäºÍ·ÓɵĽṹÖС£
4.ʹÓÃÊʵ±µÄÇý¶¯³ÌÐò»ò¿Í»§¶ËSDK´ò¿ªµ½Ä¿±êÓ¦ÓóÌÐòµÄÁ¬½Ó¡£
5.·¢ËÍÊý¾Ý²¢´¦ÀíÏìÓ¦¡£
ΪʲôÕâÊÇÒ»¸ö²»ºÃµÄÐÐΪ£¿
ËäÈ»ÄãÖ»ÓÐÕâÖÖ¼¸¸öÁ¬½Ó£¬ËüÈÔÈ»ÊǿɹÜÀíµÄ¡£Ëæ×Åϵͳ֮¼ä¹ØÏµµÄÔö¼Ó£¬Ó¦ÓóÌÐòµÄÒµÎñÂß¼Ó뼯³ÉÂß¼»ìºÏÔÚÒ»Æð£¬¼´¼¯³ÉÊý¾Ý£¬²¹³¥Á½¸öϵͳ֮¼äµÄ¼¼Êõ²îÒ죬²¢Í¨¹ýSOAP£¬REST»ò¸ü¶àÒì³£ÇëÇó½«Êý¾Ý´«Êäµ½Íⲿϵͳ¡£
Èç¹ûÄúÒª¼¯³É¶à¸öÓ¦ÓóÌÐò£¬ÄÇôÔÚÕâÑùµÄ´úÂëÖÐ×·ËÝÒÀÀµ¹ØÏµµÄÕû¸ö»ÃæÊǷdz£À§ÄѵģºÊý¾Ý²úÉúÔÚÄÄÀïÒÔ¼°ÄÄЩ·þÎñʹÓÃËü£¿Äú½«ÓÐÐí¶àµØ·½¼¯³ÉÂß¼ÖØ¸´£¬ÒÔÒýµ¼¡£
ÓÐÁËÕâÑùµÄ·½·¨£¬ËäÈ»Õâ¸öÈÎÎñÔÚ¼¼ÊõÉÏÒѾÍê³É£¬µ«ÊÇÎÒÃÇÔÚ¼¯³ÉµÄ¿Éά»¤ÐԺͿÉÉìËõÐÔ·½ÃæÓöµ½Á˺ܴóµÄÎÊÌâ¡£Õâ¸öϵͳÖÐÊý¾ÝÁ÷µÄ¿ìËÙÖØ×鼸ºõÊDz»¿ÉÄܵ쬏ü²»ÓÃ˵¸üÉî²ã´ÎµÄÎÊÌ⣬±ÈÈçȱÉÙ¼àÊÓ£¬¶Ï·£¬Êý¾Ý»Ö¸´µÈµÈ¡£
µ±½«Èí¼þ¼¯³Éµ½Ò»¸öÏ൱´óµÄÆóÒµµÄ·¶Î§Ê±£¬ÕâÒ»µãÓÈÎªÖØÒª¡£Òª´¦ÀíÆóÒµ¼¯³É£¬¾ÍÒâζ×ÅÒªÓëÒ»×éÓ¦ÓóÌÐòÒ»Æð¹¤×÷£¬ÕâЩӦÓóÌÐòÔËÐÐÔڹ㷺µÄƽ̨ÉÏ£¬²¢ÇÒ´æÔÚÓÚ²»Í¬µÄλÖá£ÔÚÕâÑùÒ»¸öÈí¼þ»·¾³ÖУ¬Êý¾Ý½»»»ÊÇÏ൱¿Á¿ÌµÄ¡£Ëü±ØÐë·ûºÏÐÐÒµµÄ¸ß°²È«±ê×¼£¬²¢Ìṩ¿É¿¿µÄÊý¾Ý´«Ê䷽ʽ¡£ÔÚÆóÒµ»·¾³ÖУ¬ÏµÍ³¼¯³ÉÐèÒªÒ»¸ö¶ÀÁ¢µÄ¡¢È«ÃæµÄ¼Ü¹¹Éè¼Æ¡£
±¾ÎĽ«ÏòÄú½éÉÜÈí¼þ¼¯³ÉÃæÁٵĶÀÌØÀ§ÄÑ£¬²¢Îª¼¯³ÉÈÎÎñÌṩһЩ¾ÑéÇý¶¯µÄ½â¾ö·½°¸¡£ÎÒÃǽ«ÊìϤApache
Camel£¬ÕâÊÇÒ»¸öÓÐÓõĿò¼Ü£¬¿ÉÒÔ¼õÇἯ³É¿ª·¢ÈËԱͷʹµÄ×Çé¿ö¡£ÎÒÃǽ«ÒÔÂæÍÕÈçºÎ°ïÖú½¨Á¢ÓÉKubernetesÌṩ֧³ÖµÄ΢·þÎñ¼¯ÈºÖеÄͨÐÅΪÀý¡£
ÕûºÏÀ§ÄÑ
½â¾ö¸ÃÎÊÌâµÄÒ»¸ö¹ã·ºÊ¹Óõķ½·¨ÊÇÔÚÓ¦ÓóÌÐòÖзÖÀëÒ»¸ö¼¯³É²ã¡£Ëü¿ÉÒÔ´æÔÚÓÚͬһ¸öÓ¦ÓóÌÐòÖУ¬Ò²¿ÉÒÔ×÷Ϊһ¸ö¶ÀÁ¢ÔËÐеÄרÓÃÈí¼þ
- ÔÚºóÒ»ÖÖÇé¿öϳÆÎªÖмä¼þ¡£
ÔÚ¿ª·¢ºÍÖ§³ÖÖмä¼þʱ£¬Äúͨ³£»áÓöµ½Ê²Ã´ÎÊÌ⣿һ°ãÀ´Ëµ£¬ÄãÓÐÒÔϹؼüµã£º
ËùÓÐÊý¾ÝͨµÀÔÚÒ»¶¨³Ì¶ÈÉ϶¼²»¿É¿¿¡£Êý¾ÝÇ¿¶ÈµÍµ½ÖеÈʱ£¬¿ÉÄܲ»»á³öÏÖÓɴ˲»¿É¿¿ÐÔÒýÆðµÄÎÊÌâ¡£´ÓÓ¦ÓóÌÐòÄÚ´æµ½ÏÂÃæµÄ»º´æºÍÉ豸µÄÿ¸ö´æ´¢¼¶±ð¶¼¿ÉÄܳöÏÖ¹ÊÕÏ¡£Ö»ÓдóÁ¿µÄÊý¾Ý²Å»á³öÏÖһЩº±¼ûµÄ´íÎó¡£¼´Ê¹³ÉÊìµÄÉú²ú¾ÍÐ÷¹©Ó¦É̲úÆ·Ò²ÓÐδ½â¾öµÄÓëÊý¾Ý¶ªÊ§ÓйصĴíÎó¸ú×ÙÆ÷ÎÊÌâ¡£Ò»¸öÖмä¼þϵͳӦ¸ÃÄܹ»Í¨ÖªÄãÕâЩÊý¾ÝµÄÉËÍö£¬²¢¼°Ê±ÌṩÏûÏ¢ÖØÐ´«µÝ¡£
Ó¦ÓóÌÐòʹÓò»Í¬µÄÐÒéºÍÊý¾Ý¸ñʽ¡£ÕâÒâζ׿¯³ÉϵͳÊÇÊý¾Ýת»»ºÍÊÊÅäÆ÷µ½ÆäËû²ÎÓëÕßµÄá¡Ä»£¬²¢ÀûÓÃÁ˸÷ÖÖ¼¼Êõ¡£ÕâЩ·½·¨¿ÉÒÔ°üÀ¨¼òµ¥µÄREST
APIµ÷Ó㬵«Ò²¿ÉÒÔ·ÃÎʶÓÁдúÀí£¬Í¨¹ýFTP·¢ËÍCSVÃüÁ»òÕß½«Êý¾ÝÅúÁ¿Íϵ½Êý¾Ý¿â±íÖС£ÕâÊÇÒ»Õų¤³¤µÄµ¥×Ó£¬Ëü²»»á±ä¶ÌµÄ¡£
Êý¾Ý¸ñʽºÍ·ÓɹæÔòµÄ±ä»¯ÊDz»¿É±ÜÃâµÄ¡£Ó¦ÓóÌÐò¿ª·¢¹ý³ÌÖеÄÿ¸ö²½Öè¶¼»á¸Ä±äÊý¾Ý½á¹¹£¬Õâͨ³£»áµ¼Ö¼¯³ÉÊý¾Ý¸ñʽºÍת»»µÄ±ä»¯¡£ÓÐʱºò£¬ÖØ×éÆóÒµÊý¾ÝÁ÷µÄ»ù´¡ÉèÊ©±ä»¯ÊDZØÒªµÄ¡£ÀýÈ磬ÒýÈëÒ»¸öÑéÖ¤²Î¿¼Êý¾ÝµÄµ¥µãʱ£¬¿ÉÄܻᷢÉúÕâЩ¸ü¸Ä£¬ÕâЩ²Î¿¼Êý¾Ý±ØÐë´¦ÀíÕû¸ö¹«Ë¾µÄËùÓÐÖ÷Êý¾ÝÌõÄ¿¡£ÓÐÁËNϵͳ£¬ÎÒÃÇ×îÖÕ¿ÉÄÜN^2ÔÚËüÃÇÖ®¼äÓÐ×î´óµÄÁ¬½Ó£¬ËùÒÔ±ØÐëÓ¦Óøü¸ÄµÄµØ·½µÄÊýÁ¿Ôö³¤µÃÏ൱¿ì¡£Õ⽫ÏñÑ©±ÀÒ»Ñù¡£ÎªÁ˱£³Ö¿Éά»¤ÐÔ£¬Öмä¼þ²ã±ØÐëͨ¹ý¶àÖÖ·ÓɺÍÊý¾Ýת»»ÌṩÇåÎúµÄÒÀÀµ¹ØÏµÍ¼¡£
ÔÚÉè¼Æ¼¯³ÉºÍÑ¡Ôñ×îºÏÊʵÄÖмä¼þ½â¾ö·½°¸Ê±£¬Ó¦¸ÃÀμÇÕâЩÏë·¨¡£´¦ÀíÕâ¸öÎÊÌâµÄ¿ÉÄÜ·½·¨Ö®Ò»ÊÇÀûÓÃÆóÒµ·þÎñ×ÜÏߣ¨ESB£©¡£µ«ÊÇÖ÷Òª¹©Ó¦ÉÌÌṩµÄESBͨ³£¹ýÓÚ³ÁÖØ£¬¶øÇÒÍùÍù±ÈËûÃǵļÛÖµ¸üÂé·³£ºESB¼¸ºõ²»¿ÉÄÜ¿ìËÙÆô¶¯£¬ËüµÄѧϰÇúÏßÏ൱¶¸ÇÍ£¬¶øÇÒËüµÄÁé»îÐÔ±»ÎþÉüÓÚÒ»³¤´®µÄ¹¦ÄܺÍÄÚÖù¤¾ß¡£ÔÚÎÒ¿´À´£¬ÇáÁ¿¼¶µÄ¿ªÔ´¼¯³É½â¾ö·½°¸ÒªÓÅÔ½µÃ¶à
- ËüÃǸü¾ßµ¯ÐÔ£¬Ò×ÓÚ²¿Êðµ½ÔÆÖУ¬²¢ÇÒÒ×ÓÚÀ©Õ¹¡£
Èí¼þ¼¯³É²¢²»ÈÝÒס£½ñÌ죬µ±ÎÒÃǹ¹½¨Î¢·þÎñ¼Ü¹¹²¢´¦Àí´óÁ¿µÄСÐÍ·þÎñʱ£¬ÎÒÃǶÔÓÚËüÃÇÓ¦¸ÃÈçºÎÓÐЧ¹µÍ¨Ò²±§ÓÐºÜ¸ßµÄÆÚÍû¡£
ÆóÒµ¼¯³Éģʽ
ÕýÈçËùÁÏ£¬ÏñÒ»°ãµÄÈí¼þ¿ª·¢Ò»Ñù£¬Êý¾Ý·ÓɺÍת»»µÄ·¢Õ¹Éæ¼°ÖØ¸´µÄ²Ù×÷¡£¾¹ýÒ»¶Îʱ¼äµÄ´¦ÀíÕûºÏÎÊÌâµÄרҵÈËÔ±¶ÔÕâ·½ÃæµÄ¾Ñé½øÐÐÁË×ܽáºÍϵͳ»¯¡£ÔÚ½á¹ûÖУ¬ÓÐÒ»×é³ÆÎªÆóÒµ¼¯³ÉģʽµÄÌáȡģ°å£¬ÓÃÓÚÉè¼ÆÊý¾ÝÁ÷¡£ÕâЩÕûºÏ·½·¨ÔÚGregor
HopheºÍBobby WolfeµÄͬÃûÊéÖÐÓÐÃèÊö£¬ÕâºÜÏñ¡°ËÄÈ˰µÄÊ飬µ«ÊÇÔÚ½ººÏÈí¼þ·½Ãæ¡£
¾ÙÒ»¸öÀý×Ó£¬¹æ·¶»¯Ä£Ê½ÒýÈëÁËÒ»¸ö×é¼þ£¬Ëü½«¾ßÓв»Í¬Êý¾Ý¸ñʽµÄÓïÒåÏàͬµÄÏûÏ¢Ó³Éäµ½µ¥¸ö¹æ·¶Ä£ÐÍ£¬»òÕß¾ÛºÏÆ÷ÊÇÒ»¸ö½«Ò»ÏµÁÐÏûÏ¢ºÏ²¢ÎªÒ»¸öµÄEIP¡£
ÓÉÓÚËüÃÇÊÇÓÃÓÚ½â¾ö¼Ü¹¹ÎÊÌâµÄ¼¼ÊõÎ޹صijéÏó£¬ËùÒÔEIPÓÐÖúÓÚ±àдһ¸ö¼Ü¹¹Éè¼Æ£¬Ëü²»»áÉîÈëµ½´úÂë¼¶±ð£¬¶øÊÇ×ã¹»ÏêϸµØÃèÊöÊý¾ÝÁ÷¡£ÕâÖÖÃèÊöÕûºÏ·ÏߵķûºÅ²»½öʹÉè¼Æ¼ò½à£¬¶øÇÒÔÚ½â¾öÓë¸÷ÒµÎñÁìÓòµÄÍŶӳÉÔ±µÄÕûºÏÈÎÎñµÄ±³¾°Ï£¬ÉèÖÃÁËÒ»¸öͨÓõÄÊõÓïºÍͨÓõÄÓïÑÔ£¬ÕâÊǷdz£ÖØÒªµÄ¡£
½éÉÜApache Camel
¼¯³É·Óɱ»Ð´³ÉÓÉ¿é×é³ÉµÄ¹ÜµÀ¡£Ëü´´½¨ÁËÒ»¸öÍêȫ͸Ã÷µÄͼÏñÀ´°ïÖú×·×ÙÊý¾ÝÁ÷¡£
ÂæÍÕÓÐÐí¶àÁ÷ÐеÄAPIÊÊÅäÆ÷¡£ÀýÈ磬´ÓApache Kafka»ñÈ¡Êý¾Ý£¬¼à¿ØAWS
EC2ʵÀý£¬ÓëSalesforce¼¯³É - ËùÓÐÕâЩÈÎÎñ¶¼¿ÉÒÔʹÓÃÏֳɵÄ×é¼þÀ´½â¾ö¡£
¼¸Äêǰ£¬ÎÒÕýÔÚÒ»¸ö´óÐÍʳƷÔÓ»õÁãÊÛÍøÂçÖн¨Á¢Ò»¸öÆóÒµ¼¯³ÉÌåϵ£¬É̵ê·Ö²¼¹ã·º¡£ÎÒ´ÓÒ»¸öרÓеÄESB½â¾ö·½°¸¿ªÊ¼£¬ºóÀ´Ö¤Ã÷Õâ¸ö·½°¸¹ýÓÚ·±Ëö¡£È»ºó£¬ÎÒÃǵÄÍŶÓÓöµ½ÁËApache
Camel£¬ÔÚ×öÁËһЩ¡°¸ÅÄîÑéÖ¤¡±¹¤×÷Ö®ºó£¬ÎÒÃÇºÜ¿ìµØ½«ËùÓеÄÊý¾ÝÁ÷¸Äд³ÉÁËCamel·ÓÉ¡£
Apache Camel¿ÉÒÔ±»ÃèÊöΪһ¸ö¡°Öнé·ÓÉÆ÷¡±£¬ËüÊÇÒ»¸öÃæÏòÏûÏ¢µÄÖмä¼þ¿ò¼Ü£¬ÊµÏÖÁËÎÒÊìϤµÄEIPÁÐ±í¡£ËüÀûÓÃÕâЩģʽ£¬Ö§³ÖËùÓг£¼ûµÄ´«ÊäÐÒ飬²¢ÇÒ°üº¬ÁË´óÁ¿ÓÐÓõÄÊÊÅäÆ÷¡£ÂæÍÕÄܹ»´¦Àí´óÁ¿µÄ¼¯³ÉÀý³Ì£¬¶øÎÞÐè±àд×Ô¼ºµÄ´úÂë¡£
³ý´ËÖ®Í⣬ÎÒ»áÑ¡³öÏÂÃæµÄApache CamelÌØÐÔ£º
¼¯³É·Óɱ»Ð´³ÉÓÉ¿é×é³ÉµÄ¹ÜµÀ¡£Ëü´´½¨ÁËÒ»¸öÍêȫ͸Ã÷µÄͼÏñÀ´°ïÖú×·×ÙÊý¾ÝÁ÷¡£
CamelÓÐÐí¶àÁ÷ÐеÄAPIÊÊÅäÆ÷¡£ÀýÈ磬´ÓApache Kafka»ñÈ¡Êý¾Ý£¬¼à¿ØAWS
EC2ʵÀý£¬ÓëSalesforce¼¯³É - ËùÓÐÕâЩÈÎÎñ¶¼¿ÉÒÔʹÓÃÏֳɵÄ×é¼þÀ´½â¾ö¡£
Apache Camel·ÓÉ¿ÉÒÔÓÃJava»òScala DSL±àд¡££¨XMLÅäÖÃÒ²¿ÉÓ㬵«¹ýÓÚÈß³¤£¬µ÷ÊÔ¹¦Äܸü²î£©¡£Ëü²»»á¶ÔͨÐÅ·þÎñµÄ¼¼Êõ¶Ñջʩ¼ÓÏÞÖÆ£¬µ«ÊÇÈç¹ûÄúʹÓÃJava»òScala±àд£¬Ôò¿ÉÒÔ½«CamelǶÈëµ½Ó¦ÓóÌÐòÖжÀÁ¢ÔËÐС£
CamelʹÓõÄ·ÓÉ·ûºÅ¿ÉÒÔÓÃÏÂÃæµÄ¼òµ¥Î±´úÂëÀ´ÃèÊö£º
from(Source)
.transform(Transformer)
.to(Destination)
|
µÄSource£¬TransformerÒÔ¼°DestinationÊÇÖ¸ÓÉÆäuriÖ¸ÏòʵÏÖ×é¼þµÄ¶Ëµã¡£
ÊÇʲôÈÃCamel½â¾öÁËÎÒ֮ǰÃèÊöµÄÕûºÏÎÊÌ⣿ÎÒÃÇÀ´¿´Ò»Ï¡£Ê×ÏÈ£¬Â·ÓɺÍת»»Âß¼ÏÖÔÚÖ»ÄÜÓÃÓÚרÃŵÄApache
CamelÅäÖá£Æä´Î£¬Í¨¹ý¼ò½à×ÔÈ»µÄDSL½áºÏEIPµÄʹÓ㬳öÏÖÁËϵͳ֮¼äµÄÒÀÀµ¹ØÏµÍ¼¡£ËüÓÉÒ×Àí½âµÄ³éÏ󹹳ɣ¬Â·ÓÉÂß¼Ò×ÓÚµ÷Õû¡£×îºó£¬ÎÒÃDz»±Ø±àдת»»´úÂëµÄ¶Ñ£¬ÒòΪÊʵ±µÄÊÊÅäÆ÷¿ÉÄÜÒѾ°üº¬ÔÚÄÚ¡£

ÎÒÓ¦¸Ã²¹³äÒ»µã£¬Apache CamelÊÇÒ»¸ö³ÉÊìµÄ¿ò¼Ü£¬²¢¶¨ÆÚ¸üС£ËüÓÐÒ»¸öΰ´óµÄÉçÇøºÍÏ൱ÅÓ´óµÄ֪ʶ¿â¡£
ËüȷʵÓÐËü×Ô¼ºµÄȱµã¡£ÂæÍÕ²»Ó¦¸Ã±»ÊÓΪһ¸ö¸´ÔÓµÄÕûºÏÌ×¼þ¡£ÕâÊÇÒ»¸öûÓи߼¶¹¦ÄÜ£¨ÈçÒµÎñÁ÷³Ì¹ÜÀí¹¤¾ß»ò»î¶¯¼àÊÓÆ÷£©µÄ¹¤¾ßÏ䣬µ«¿ÉÓÃÓÚ´´½¨´ËÀàÈí¼þ¡£
Ìæ´úϵͳ¿ÉÄÜÊÇ£¬ÀýÈçSpring Integration»òMule
ESB¡£¶ÔÓÚSpring IntegrationÀ´Ëµ£¬¾¡¹ÜËü±»ÈÏΪÊÇÇáÁ¿¼¶µÄ£¬µ«¸ù¾ÝÎҵľÑ飬°ÑËü·ÅÔÚÒ»Æð²¢±àд´óÁ¿µÄXMLÅäÖÃÎļþ¿ÉÄÜ»á±äµÃÒì³£¸´ÔÓ£¬²¢ÇÒ²»ÊÇÒ»¸ö¼òµ¥µÄ³ö·¡£Mule
ESBÊÇÒ»¸ö¹¦ÄÜÇ¿´óÇÒ¹¦ÄÜÇ¿´óµÄ¹¤¾ß¼¯£¬µ«¹ËÃû˼Ò壬ËüÊÇÒ»ÖÖÆóÒµ·þÎñ×ÜÏߣ¬Òò´ËËüÊôÓÚ²»Í¬µÄÈ¨ÖØÀà±ð¡£Mule¿ÉÒÔÓëFuse
ESB½øÐбȽϣ¬Fuse ESBÊÇÒ»¿î»ùÓÚApache CamelµÄÀàËÆ²úÆ·£¬¾ßÓзḻµÄ¹¦ÄÜ¡£¶ÔÎÒÀ´Ëµ£¬Ê¹ÓÃApache
CamelÀ´Õ³Ìù·þÎñÊÇÒ»¼þ²»ÈÝÒ×µÄÊÂÇé¡£ËüºÜÈÝÒ×ʹÓ㬲¢²úÉúÒ»¸ö¸É¾»µÄÃèÊö£¬ÔÚʲôµØ·½£¬Í¬Ê±£¬ËüµÄ¹¦ÄÜ×ã¹»½¨É踴Ôӵɡ£
±àдһ¸öʾÀý·Ïß
ÎÒÃÇ¿ªÊ¼±àд´úÂë¡£ÎÒÃǽ«´ÓÒ»¸öͬ²½Êý¾ÝÁ÷¿ªÊ¼£¬Õâ¸öÊý¾ÝÁ÷½«ÏûÏ¢´Óµ¥Ò»À´Ô´Â·Óɵ½ÊÕ¼þÈËÁÐ±í¡£Â·ÓɹæÔò½«ÓÃJava
DSL±àд¡£
ÎÒÃǽ«Ê¹ÓÃMaven¹¹½¨ÏîÄ¿¡£Ê×ÏȽ«ÒÔÏÂÒÀÀµÏîÌí¼Óµ½pom.xml£º
<dependencies>
...
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-core</artifactId>
<version>2.20.0</version>
</dependency>
</dependencies>
|
»òÕߣ¬Ó¦ÓóÌÐò¿ÉÒÔ½¨Á¢ÔÚcamel-archetype-javaÔÐÍÖ®ÉÏ¡£
Camel·¾¶¶¨ÒåÔÚRouteBuilder.configure·½·¨ÖÐÉùÃ÷¡£
public
void configure() {
errorHandler(defaultErrorHandler().maximum
Redeliveries(0));
from("file:orders?noop=true").routeId("main")
.log("Incoming File: ${file:onlyname}")
.unmarshal().json(JsonLibrary.Jackson,
Order.class)
// unmarshal JSON
to Order class containing
List
<OrderItem>
.split().simple("body.items") // split
list to
process one by one
.to("log:inputOrderItem")
.choice()
.when().simple("${body.type} == 'Drink'")
.to("direct:bar")
.when().simple("${body.type} == 'Dessert'")
.to("direct:dessertStation")
.when().simple("${body.type} == 'Hot Meal'")
.to("direct:hotMealStation")
.when().simple("${body.type} == 'Cold Meal'")
.to("direct:coldMealStation")
.otherwise()
.to("direct:others");
from("direct:bar").routeId("bar").log
("Handling
Drink");
from("direct:dessertStation").routeId
("dessertStation").
log("Handling
Dessert");
from("direct:hotMealStation").routeId
("hotMealStation").
log("Handling
Hot Meal");
from("direct:coldMealStation").routeId
("coldMealStation").
log("Handling
Cold Meal");
from("direct:others").routeId("others")
.log("Handling
Something Other");
} |
ÔÚÕâ¸ö¶¨ÒåÖУ¬ÎÒÃÇ´´½¨ÁËÒ»¸ö´ÓJSONÎļþÖлñÈ¡¼Ç¼µÄ·¾¶£¬½«ËüÃDzð·Ö³ÉÌõÄ¿£¬²¢¸ù¾ÝÏûÏ¢ÄÚÈÝ·Óɵ½Ò»×é´¦Àí³ÌÐò¡£
ÈÃÎÒÃÇÔÚ×¼±¸ºÃµÄ²âÊÔÊý¾ÝÉÏÔËÐÐËü¡£ÎÒÃǽ«µÃµ½Êä³ö£º
INFO | Total 6 routes, of which 6 are started
INFO | Apache Camel 2.20.0 (CamelContext:
camel-1) started
in 10.716 seconds
INFO | Incoming File: order1.json
INFO | Exchange[ExchangePattern: InOnly,
BodyType: com.antongoncharov.camel.example.model
.OrderItem, Body:
OrderItem{id='1', type='Drink', name='Americano',
qty='1'}]
INFO | Handling Drink
INFO | Exchange[ExchangePattern: InOnly,
BodyType: com.antongoncharov.camel.example.model.OrderItem,
Body: OrderItem{id='2', type='Hot Meal',
name='French Omelette',
qty='1'}]
INFO | Handling Hot Meal
INFO | Exchange[ExchangePattern: InOnly,
BodyType: com.antongoncharov.camel.example.
model.
OrderItem, Body:
OrderItem{id='3', type='Hot
Meal', name='Lasagna',
qty='1'}]
INFO | Handling Hot Meal
INFO | Exchange[ExchangePattern: InOnly,
BodyType: com.antongoncharov.camel.example.model.OrderItem,
Body: OrderItem{id='4', type='Hot Meal',
name='Rice Balls',
qty='1'}]
INFO | Handling Hot Meal
INFO | Exchange[ExchangePattern: InOnly,
BodyType: com.antongoncharov.camel.example.model.
OrderItem, Body:
OrderItem{id='5', type='Dessert', name='Blueberry
Pie', qty='1'}]
INFO | Handling Dessert |
ÕýÈçËùÁÏ£¬Camel·ÓÉÏûÏ¢µ½Ä¿µÄµØ¡£
Êý¾Ý´«ÊäÑ¡Ôñ
ÔÚÉÏÃæµÄʾÀýÖУ¬×é¼þÖ®¼äµÄ½»»¥ÊÇͬ²½µÄ£¬²¢Í¨¹ýÓ¦ÓóÌÐòÄÚ´æÖ´ÐС£µ«ÊÇ£¬µ±ÎÒÃÇ´¦Àí²»¹²ÏíÄÚ´æµÄµ¥¶ÀÓ¦ÓóÌÐòʱ£¬»¹Óиü¶àµÄͨÐÅ·½Ê½£º
1.Îļþ½»»»¡£Ò»¸öÓ¦ÓóÌÐò²úÉú¹²ÏíÊý¾ÝÎļþ¹©ÁíÒ»¸öʹÓá£ÕâÊÇÀÏÅɾ«ÉñµÄÉú´æÖ®µØ¡£ÕâÖÖ¹µÍ¨·½Ê½´øÀ´ÁËÖî¶àºó¹û£ºÈ±·¦½»Ò׺ÍÒ»ÖÂÐÔ£¬ÐÔÄܽϲϵͳ֮¼äµÄ¹ÂÁ¢Ðµ÷¡£Ðí¶à¿ª·¢ÈËÔ±×îÖÕ±àдÁË×ÔÖÆµÄ¼¯³É½â¾ö·½°¸£¬Ê¹Õâ¸ö¹ý³Ì»ò¶à»òÉٵؿÉÒÔ¹ÜÀí¡£
2.ͨÓÃÊý¾Ý¿â¡£ÈÃÓ¦ÓóÌÐò½«ËûÃÇÏ£Íû¹²ÏíµÄÊý¾Ý´æ´¢ÔÚµ¥¸öÊý¾Ý¿âµÄͨÓÃģʽÖС£Éè¼ÆÍ³Ò»Ä£Ê½ºÍ´¦Àí²¢·¢·ÃÎʱíÊÇÕâÖÖ·½·¨×îÍ»³öµÄÌôÕ½¡£ÓëÎļþ½»»»Ò»Ñù£¬ÕâºÜÈÝÒ׳ÉΪÓÀ¾ÃµÄÆ¿¾±¡£
3.Ô¶³ÌAPIµ÷Óá£Ìṩһ¸ö½Ó¿Ú£¬ÔÊÐíÓ¦ÓóÌÐòÓëÁíÒ»¸öÕýÔÚÔËÐеÄÓ¦ÓóÌÐò½øÐн»»¥£¬ÈçµäÐ͵ķ½·¨µ÷Óá£Ó¦ÓóÌÐòͨ¹ýAPIµ÷Óù²Ïí¹¦ÄÜ£¬µ«ÊÇËüÔÚ¹ý³ÌÖнôÃÜñîºÏËüÃÇ¡£
4.ÏûÏ¢¡£ÈÃÿ¸öÓ¦ÓóÌÐòÁ¬½Óµ½Ò»¸öͨÓõÄÏûÏ¢´«µÝϵͳ£¬²¢Ê¹ÓÃÏûÏ¢Òì²½½»»»Êý¾ÝºÍµ÷ÓÃÐÐΪ¡£·¢ËÍÕߺͽÓÊÕÕß¶¼²»±ØÍ¬Ê±Æô¶¯²¢ÔËÐÐÏûÏ¢¡£
Óиü¶àµÄ½»»¥·½Ê½£¬µ«ÊÇÎÒÃÇÓ¦¸Ã¼Çס£¬´Ó¹ãÒåÉϽ²£¬ÓÐÁ½ÖÖÀàÐ͵Ľ»»¥£ºÍ¬²½ºÍÒì²½¡£µÚÒ»¸ö¾ÍÏñÔÚÄãµÄ´úÂëÖе÷ÓÃÒ»¸öº¯Êý
- Ö´ÐÐÁ÷³Ì½«Ò»Ö±µÈ´ý£¬Ö±µ½ËüÖ´Ðв¢·µ»ØÒ»¸öÖµ¡£Ê¹ÓÃÒì²½·½·¨£¬ÏàͬµÄÊý¾Ýͨ¹ýÖмäÏûÏ¢¶ÓÁлò¶©ÔÄÖ÷Ìâ·¢ËÍ¡£Òì²½Ô¶³Ìº¯Êýµ÷ÓÿÉÒÔ×÷ΪÇëÇó
- »Ø¸´EIPÀ´ÊµÏÖ¡£
Òì²½ÏûÏ¢´«µÝ²»ÊÇÍòÄܵģ¬ËüÉæ¼°µ½Ò»¶¨µÄÏÞÖÆ¡£ÄúºÜÉÙÔÚÍøÂçÉÏ¿´µ½ÏûÏ¢API;
ͬ²½REST·þÎñ¸üÊÜ»¶Ó¡£µ«ÊÇÏûÏ¢Öмä¼þ±»¹ã·ºÓÃÓÚÆóÒµÄÚ²¿Íø»ò·Ö²¼Ê½ÏµÍ³ºó¶Ë»ù´¡ÉèÊ©¡£
ʹÓÃÏûÏ¢¶ÓÁÐ
ÈÃÎÒÃǵÄʾÀýÒì²½¡£¹ÜÀí¶ÓÁкͶ©ÔÄÖ÷ÌâµÄÈí¼þϵͳ³ÆÎªÏûÏ¢´úÀí¡£Õâ¾ÍÏñÒ»¸ö±íºÍÁеÄRDBMS¡£¶ÓÁÐÓÃ×÷µã¶Ôµã¼¯³É£¬¶øÖ÷ÌâÓÃÓÚÓëÐí¶à½ÓÊÕÕߵķ¢²¼
- ¶©ÔÄͨÐÅ¡£ÎÒÃǽ«Ê¹ÓÃApache ActiveMQ×÷ΪJMSÏûÏ¢´úÀí£¬ÒòΪËüÊǿɿ¿ÇÒ¿ÉǶÈëµÄ¡£
Ìí¼ÓÒÔÏÂÒÀÀµÏî¡£ÓÐʱactivemq-all£¬ÏòÏîÄ¿ÖÐÌí¼Ó°üº¬ËùÓÐActiveMQ
jar µÄ¹ý¶È£¬µ«ÎÒÃǻᱣ³ÖÎÒÃǵÄÓ¦ÓóÌÐòµÄÒÀÀµ¹ØÏµ²»¸´ÔÓ¡£
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-all</artifactId>
<version>5.15.2</version>
</dependency>
|
È»ºóÒÔ±à³Ì·½Ê½Æô¶¯´úÀí¡£ÔÚSpring BootÖУ¬Í¨¹ý²åÈëspring-boot-starter-activemqMavenÒÀÀµ¹ØÏµ£¬ÎÒÃǵõ½ÁËÒ»¸ö×Ô¶¯ÅäÖá£
ʹÓÃÒÔÏÂÃüÁîÔËÐÐеÄÏûÏ¢´úÀí£¬Ö»Ö¸¶¨Á¬½ÓÆ÷µÄ¶Ëµã£º
BrokerService broker = new BrokerService();
broker.addConnector("tcp://localhost:61616");
broker.start();
|
²¢½«ÒÔÏÂÅäÖÃÆ¬¶ÎÌí¼Óµ½configure·½·¨Ì壺
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://localhost:61616");
this.getContext().addComponent("activemq",
ActiveMQComponent.jmsComponent(connectionFactory));
|
ÏÖÔÚÎÒÃÇ¿ÉÒÔʹÓÃÏûÏ¢¶ÓÁÐÀ´¸üÐÂÇ°ÃæµÄÀý×Ó¡£¶ÓÁн«×Ô¶¯´´½¨ÏûÏ¢´«µÝ¡£
public
void configure() {
errorHandler(defaultErrorHandler().maximumRede
liveries(0));
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://localhost:61616");
this.getContext().addComponent("activemq",
ActiveMQComponent.jmsComponent(connectionFactory));
from("file:orders?noop=true").routeId("main")
.log("Incoming File: ${file:onlyname}")
.unmarshal().json(JsonLibrary.Jackson, Order.class)
// unmarshal JSON
to Order class containing
List<OrderItem>
.split().simple("body.items") // split
list
to process one by
one
.to("log:inputOrderItem")
.choice()
.when().simple("${body.type} == 'Drink'")
.to("activemq:queue:bar")
.when().simple("${body.type} == 'Dessert'")
.to("activemq:queue:dessertStation")
.when().simple("${body.type} == 'Hot Meal'")
.to("activemq:queue:hotMealStation")
.when().simple("${body.type} == 'Cold Meal'")
.to("activemq:queue:coldMealStation")
.otherwise()
.to("activemq:queue:others");
from("activemq:queue:bar").routeId("barAsync").
log("Drinks");
from("activemq:queue:dessertStation").routeId
("dessertAsync").log("Dessert");
from("activemq:queue:hotMealStation").routeId
from("activemq:queue:coldMealStation").routeId
("coldMealAsync").log("Cold
Meals");
from("activemq:queue:others").routeId("othersAsync")
.log("Others"); |
ºÃÁË£¬ÏÖÔÚ½»»¥ÒѾ±äµÃÒì²½ÁË¡£ÕâЩÊý¾ÝµÄDZÔÚÏû·ÑÕßÔÚ×¼±¸ºÃʱ¿ÉÒÔ·ÃÎÊËü¡£ÕâÊÇÒ»¸öËÉñîºÏµÄÀý×Ó£¬ÎÒÃÇÊÔͼÔÚÒ»¸ö±»¶¯µÄ¼Ü¹¹ÖÐʵÏÖ¡£ÆäÖÐÒ»Ïî·þÎñ²»¿ÉÓý«²»»á×èÖ¹ÆäËû·þÎñ¡£¶øÇÒ£¬Ïû·ÑÕß¿ÉÒÔ²¢ÐеشӶÓÁÐÖÐËõ·ÅºÍ¶ÁÈ¡¡£¶ÓÁб¾Éí¿ÉÒÔÀ©Õ¹ºÍ·ÖÇø¡£³Ö¾Ã¶ÓÁпÉÒÔ½«Êý¾Ý´æ´¢ÔÚ´ÅÅÌÉÏ£¬µÈ´ý´¦Àí£¬¼´Ê¹ËùÓвÎÓëÕß¶¼¹Ø±ÕÁË¡£Òò´Ë£¬Õâ¸öϵͳ¸üÈÝ´í¡£
Ò»¸ö¾ªÈ˵ÄÊÂʵÊÇ£¬CERNʹÓÃApache CamelºÍActiveMQÀ´¼àÊÓ´óÐÍÇ¿×Ó¶Ôײ»ú£¨LHC£©µÄϵͳ¡£»¹ÓÐÒ»¸öÓÐȤµÄ˶ʿÂÛÎĽâÊÍÁËΪÕâ¸öÈÎÎñÑ¡ÔñºÏÊʵÄÖмä¼þ½â¾ö·½°¸¡£ËùÒÔ£¬ÕýÈçËûÃÇÔÚÖ÷ÌâÑݽ²ÖÐËù˵£º¡°Ã»ÓÐJMS-ûÓÐÁ£×ÓÎïÀíѧ£¡¡±
¼à¿Ø
ÔÚÇ°ÃæµÄÀý×ÓÖУ¬ÎÒÃÇ´´½¨ÁËÁ½¸ö·þÎñÖ®¼äµÄÊý¾ÝͨµÀ¡£ÕâÊǼܹ¹ÖÐÒ»¸ö¶îÍâµÄDZÔÚʧ°Üµã£¬ËùÒÔÎÒÃDZØÐëÕÕ¹ËËü¡£ÎÒÃÇÀ´¿´¿´Apache
CamelÌṩµÄ¼àÊÓ¹¦ÄÜ¡£»ù±¾ÉÏ£¬Ëüͨ¹ýJMXÌṩÓÐ¹ØÆä·ÓɵÄͳ¼ÆÐÅÏ¢¡£ActiveMQÒÔÏàͬµÄ·½Ê½¹«¿ª¶ÓÁÐͳ¼ÆÐÅÏ¢¡£
ÎÒÃÇ´ò¿ªÓ¦ÓóÌÐòÖеÄJMX·þÎñÆ÷£¬Ê¹ÆäÄܹ»Ê¹ÓÃÃüÁîÐÐÑ¡ÏîÔËÐУº
-Dorg.apache.camel.jmx.createRmiConne
ctor=true
-Dorg.apache.camel.jmx.mbeanObjectDoma
inName=org.apache.camel
-Dorg.apache.camel.jmx.rmiConnector.
registryPort=1099
-Dorg.apache.camel.jmx.serviceUrlPath
=camel |
ÏÖÔÚÔËÐиÃÓ¦ÓóÌÐò£¬ÒÔ±ã¸Ã·ÏßÒÑÍê³ÉÆä¹¤×÷¡£´ò¿ª±ê×¼jconsole¹¤¾ß²¢Á¬½Óµ½Ó¦ÓóÌÐò½ø³Ì¡£Á¬½Óµ½ÍøÖ·service:jmx:rmi:///jndi/rmi://localhost:1099/camel¡£×ªµ½MBeansÊ÷ÖеÄorg.apache.camelÓò¡£

ÎÒÃÇ¿ÉÒÔ¿´µ½£¬¹ØÓÚ·ÓɵÄÒ»Çж¼ÔÚ¿ØÖÆÖ®ÖС£ÎÒÃÇÓÐÕýÔÚ½øÐеÄÏûÏ¢µÄÊýÁ¿£¬´íÎó¼ÆÊýºÍ¶ÓÁÐÖеÄÏûÏ¢¼ÆÊý¡£ÕâЩÐÅÏ¢¿ÉÒÔͨ¹ýÁ÷Ë®ÏßÁ¬½Óµ½Ò»Ð©¼àÊÓ¹¤¾ß¼¯£¬ÈçGraphana»òKibana¡£Äã¿ÉÒÔͨ¹ýʵÏÖÖªÃûµÄELKÕ»À´×öµ½ÕâÒ»µã¡£
»¹ÓÐÒ»¸ö¿É²å°ÎºÍ¿ÉÀ©Õ¹µÄWeb¿ØÖÆÌ¨ÌṩÁËÒ»¸öÓû§½çÃæ£¬ÓÃÓÚ¹ÜÀíÂæÍÕµÄActiveMQ£¬ºÍ¸ü¶àµÄÈË£¬½Ðhawt.io¡£

²âÊÔ·Ïß
Apache Camel¾ßÓÐÏ൱¹ã·ºµÄ¹¦ÄÜ£¬¿ÉÒÔÓÃÄ£Äâ×é¼þ±àд²âÊÔ·ÓÉ¡£ÕâÊÇÒ»¸öÇ¿´óµÄ¹¤¾ß£¬µ«ÊÇΪÁ˲âÊÔ¶ø±àдµ¥¶ÀµÄ·ÓÉÊÇÒ»¸öºÄʱµÄ¹ý³Ì¡£ÔÚÉú²úÏßÉÏÔËÐвâÊÔ¶ø²»Ð޸ĹÜÏß»á¸üÓÐЧÂÊ¡£ÂæÍÕÓÐÕâ¸ö¹¦ÄÜ£¬¿ÉÒÔʹÓÃAdviceWith×é¼þÀ´ÊµÏÖ¡£
ÈÃÎÒÃÇÔÚÎÒÃǵÄʾÀýÖÐÆôÓòâÊÔÂß¼²¢ÔËÐÐʾÀý²âÊÔ¡£
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-test</artifactId>
<version>2.20.0</version>
<scope>test</scope>
</dependency>
|
²âÊÔÀàÊÇ£º
public class AsyncRouteTest extends CamelTestSupport
{
@Override
protected RouteBuilder createRouteBuilder()
throws Exception {
return new AsyncRouteBuilder();
}
@Before
public void mockEndpoints() throws Exception
{
context.getRouteDefinition("main").adviceWith(context,
new AdviceWithRouteBuilder() {
@Override
public void configure() throws Exception {
// we substitute all actual queues with mock
endpoints
mockEndpointsAndSkip("activemq:queue:bar");
mockEndpointsAndSkip("activemq:queue:dessertStation");
mockEndpointsAndSkip("activemq:queue:hotMealStation");
mockEndpointsAndSkip("activemq:queue:coldMealStation");
mockEndpointsAndSkip("activemq:queue:others");
// and replace the route's source with test
endpoint
replaceFromWith("file://testInbox");
}
});
}
@Test
public void testSyncInteraction() throws InterruptedException
{
String testJson = "{\"id\": 1,
\"order\": [{\"id\": 1,
\"name\": \"Americano\",
\"type\": \"Drink\", \"qty\":
\"1\"}, {\"id\": 2, \"name\":
\"French Omelette\", \"type\":
\"Hot Meal\", \"qty\": \"1\"},
{\"id\": 3, \"name\": \"Lasagna\",
\"type\": \"Hot Meal\",
\"qty\": \"1\"}, {\"id\":
4, \"name\": \"Rice Balls\",
\"type\": \"Hot Meal\",
\"qty\": \"1\"}, {\"id\":
5, \"name\": \"Blueberry Pie\",
\"type\": \"Dessert\", \"qty\":
\"1\"}]}";
// get mocked endpoint and set an expectation
MockEndpoint mockEndpoint = getMockEndpoint("mock:activemq:queue:hotMealStation");
mockEndpoint.expectedMessageCount(3);
// simulate putting file in the inbox folder
template.sendBodyAndHeader("file://testInbox",
testJson, Exchange.FILE_NAME, "test.json");
//checks that expectations were met
assertMockEndpointsSatisfied();
}
}
|
ÏÖÔÚÔËÐÐÓëÓ¦ÓóÌÐòµÄ²âÊÔmvn test¡£ÎÒÃÇ¿ÉÒÔ¿´µ½£¬ÎÒÃǵÄ·ÏßÒѾ³É¹¦µØÍ¨¹ýÁ˲âÊÔ½¨Ò顣ûÓÐÏûϢͨ¹ýʵ¼ÊµÄ¶ÓÁд«µÝ£¬²âÊÔÒѾͨ¹ý¡£
INFO
| Route: main started and consuming from: file://testInbox
<...>
INFO | Incoming File: test.json
<...>
INFO | Asserting: mock://activemq:queue:hotMealStation
is satisfied |
½ñÌìµÄÒ»¸ö¼¯³ÉÎÊÌâÊÇÓ¦ÓóÌÐò²»ÔÙÊǾ²Ì¬µÄ¡£ÔÚÔÆ»ù´¡¼Ü¹¹ÖУ¬ÎÒÃÇͬʱ´¦ÀíÔÚ¶à¸ö½ÚµãÉÏÔËÐеÄÐéÄâ·þÎñ¡£ËüʹµÃ΢·þÎñ¼Ü¹¹Äܹ»ÓëСÐÍ£¬ÇáÁ¿¼¶·þÎñÍøÂçÏ໥×÷Óá£ÕâЩ·þÎñµÄÊÙÃüÊDz»¿É¿¿µÄ£¬ÎÒÃDZØÐ붯̬µØ·¢ÏÖËüÃÇ¡£
½«ÔÆ·þÎñºÏ²¢ÔÚÒ»ÆðÊÇApache Camel¿ÉÒÔ½â¾öµÄÈÎÎñ¡£ÌرðÓÐȤµÄÊÇ£¬ÓÉÓÚEIPµÄ·ç¸ñºÍÂæÍÕÓÐ×ã¹»µÄÊÊÅäÆ÷ºÍÖ§³Ö¶àÖÖÐÒéµÄÊÂʵ¡£×î½üµÄ2.18°æ±¾Ìí¼ÓÁËServiceCall×é¼þ£¬¸Ã×é¼þÒýÈëÁ˵÷ÓÃAPI²¢Í¨¹ý¼¯Èº·¢ÏÖ»úÖÆ½âÎöÆäµØÖ·µÄ¹¦ÄÜ¡£Ä¿Ç°£¬ËüÖ§³ÖConsul£¬Kubernetes£¬RibbonµÈ¡£¿ÉÒÔºÜÈÝÒ×µØÕÒµ½´úÀíµÄһЩÀý×Ó£¬ÆäÖÐServiceCallÓÃConsulÅäÖá£ÎÒÃǽ«ÔÚÕâÀïʹÓÃKubernetes£¬ÒòΪÕâÊÇÎÒ×îϲ»¶µÄ¼¯Èº½â¾ö·½°¸¡£
ÕûºÏ¼Ü¹¹ÈçÏ£º

¸ÃOrder·þÎñºÍInventory·þÎñ½«ÊÇÒ»¸ö¼òµ¥µÄSpring
BootÓ¦ÓóÌÐò·µ»Ø¾²Ì¬Êý¾Ý¡£ÎÒÃDz»Êǰó¶¨ÔÚÕâÀïµÄÒ»¸öÌØ¶¨µÄ¼¼Êõ¶ÑÕ»¡£ÕâЩ·þÎñÕýÔÚ²úÉúÎÒÃÇÏëÒª´¦ÀíµÄÊý¾Ý¡£
¶©¹º·þÎñ¿ØÖÆÆ÷£º
@RestController
public class OrderController {
private final OrderStorage orderStorage;
@Autowired
public OrderController(OrderStorage orderStorage)
{
this.orderStorage = orderStorage;
}
@RequestMapping("/info")
public String info() {
return "Order Service UUID = " + OrderApplication.serviceID;
}
@RequestMapping("/orders")
public List<Order> getAll() {
return orderStorage.getAll();
}
@RequestMapping("/orders/{id}")
public Order getOne(@PathVariable Integer id)
{
return orderStorage.getOne(id);
}
} |
ËüÒÔÈçϸñʽ²úÉúÊý¾Ý£º
[{"id":1,"items":[2,3,4]},{"id":2,"items":[5,3]}] |
¸ÃInventory·þÎñ¿ØÖÆÆ÷ÊÇÍêÈ«ÀàËÆOrder·þÎñµÄ£º
@RestController
public class InventoryController {
private final InventoryStorage inventoryStorage;
@Autowired
public InventoryController(InventoryStorage
inventoryStorage) {
this.inventoryStorage = inventoryStorage;
}
@RequestMapping("/info")
public String info() {
return "Inventory Service UUID = "
+ InventoryApplication.serviceID;
}
@RequestMapping("/items")
public List<InventoryItem> getAll() {
return inventoryStorage.getAll();
}
@RequestMapping("/items/{id}")
public InventoryItem getOne(@PathVariable Integer
id) {
return inventoryStorage.getOne(id);
}
} |
InventoryStorageÊDZ£´æÊý¾ÝµÄͨÓô洢¿â¡£ÔÚÕâ¸öÀý×ÓÖУ¬Ëü·µ»Ø¾²Ì¬Ô¤¶¨ÒåµÄ¶ÔÏó£¬ÕâЩ¶ÔÏó±»·âË͵½ÏÂÃæµÄ¸ñʽ¡£
[{"id":1,"name":"Laptop","description":"Up
to 12-hours battery life","price":499.9},{"id":2,"name" |
ÈÃÎÒÃDZàдһ¸öÁ¬½ÓËüÃǵÄÍø¹ØÂ·ÓÉ£¬µ«ÔÚÕâ¸ö²½ÖèÖÐûÓÐServiceCall£º
rest("/orders")
.get("/").description("Get all
orders with details").outType(TestResponse.class)
.route()
.setHeader("Content-Type", constant("application
/json"))
.setHeader("Accept", constant("application/json"))
.setHeader(Exchange.HTTP_METHOD, constant("GET"))
.removeHeaders("CamelHttp*")
.to("http4://localhost:8082/orders?bridgeEndpoint
=true")
.unmarshal(formatOrder)
.enrich("direct:enrichFromInventory",
new OrderAggregationStrategy())
.to("log:result")
.endRest();
from("direct:enrichFromInventory")
.transform().simple("${null}")
.setHeader("Content-Type", constant("application/
json"))
.setHeader("Accept", constant("application/json"))
.setHeader(Exchange.HTTP_METHOD, constant("GET"))
.removeHeaders("CamelHttp*")
.to("http4://localhost:8081/items?bridgeEndpoint=
true")
.unmarshal(formatInventory); |
ÏÖÔÚÏëÏóһϣ¬Ã¿¸ö·þÎñ²»ÔÙÊÇÒ»¸öÌØ¶¨µÄʵÀý£¬¶øÊÇÒ»¸öÔËÐÐÒ»¸öʵÀýµÄÔÆ¡£ÎÒÃǽ«Ê¹ÓÃMinikubeÔÚ±¾µØ³¢ÊÔKubernetes¼¯Èº¡£
ÅäÖÃÍøÂç·ÓÉÒÔÔÚ±¾µØ²é¿´Kubernetes½Úµã£¨
# remove existing routes
sudo route -n delete 10/24 > /dev/null 2>&1
# add routes
sudo route -n add 10.0.0.0/24 $(minikube ip)
# 172.17.0.0/16 ip range is used by docker
in minikube
sudo route -n add 172.17.0.0/16 $(minikube ip)
ifconfig 'bridge100' | grep member | awk '
{print $2}¡¯
# use interface name from the output of the
previous command
# needed for xhyve driver, which I'm using
for testing
sudo ifconfig bridge100 -hostfilter en5
|
¸ø³öµÄʾÀýÊÊÓÃÓÚMac / Linux»·¾³£©£º
ʹÓÃDockerfileÅäÖý«·þÎñ°ü×°ÔÚDockerÈÝÆ÷ÖУ¬ÈçÏÂËùʾ£º
FROM openjdk:8-jdk-alpine
VOLUME /tmp
ADD target/order-srv-1.0-SNAPSHOT.jar app.jar
ADD target/lib lib
ENV JAVA_OPTS=""
ENTRYPOINT exec java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom
-jar /app.jar |
¹¹½¨²¢½«·þÎñÓ³ÏñÍÆË͵½Docker×¢²á±í¡£ÏÖÔÚÔËÐб¾µØKubernetes¼¯ÈºÖеĽڵ㡣
Kubernetes.yaml²¿ÊðÅäÖãº
apiVersion:
extensions/v1beta1
kind: Deployment
metadata:
name: inventory
spec:
replicas: 3
selector:
matchLabels:
app: inventory
template:
metadata:
labels:
app: inventory
spec:
containers:
- name: inventory
image: inventory-srv:latest
imagePullPolicy: Never
ports:
- containerPort: 8081 |
½«ÕâЩ²¿Êð×÷Ϊ¼¯ÈºÖеķþÎñ¹«¿ª£º
kubectl expose deployment order-srv --type=NodePort
kubectl expose deployment inventory-srv --type=NodePort
|
ÏÖÔÚÎÒÃÇ¿ÉÒÔ¼ì²éÇëÇóÊÇ·ñÓɼ¯ÈºÖÐËæ»úÑ¡ÔñµÄ½ÚµãÌṩ·þÎñ¡£curl
-X http://192.168.99.100:30517/infoÒÀ´ÎÔËÐм¸´ÎÒÔ·ÃÎÊminikube
NodePortÒÔ»ñµÃ¹«¿ªµÄ·þÎñ£¨Ê¹ÓÃÄúµÄÖ÷»úºÍ¶Ë¿Ú£©¡£ÔÚÊä³öÖУ¬ÎÒÃÇ¿´µ½ÎÒÃÇÒѾʵÏÖÁËÇëÇóÆ½ºâ¡£
Inventory
Service UUID = 22f8ca6b-f56b-4984-927b-cbf9fcf81da5
Inventory Service UUID = b7a4d326-1e76-4051-a0a6-1016394fafda
Inventory Service UUID = b7a4d326-1e76-4051-a0a6-1016394fafda
Inventory Service UUID = 22f8ca6b-f56b-4984-927b-cbf9fcf81da5
Inventory Service UUID = 50323ddb-3ace-4424-820a-6b4e85775af4 |
Ìí¼Ócamel-kubernetesºÍcamel-netty4-httpÒÀÀµÏîÄ¿µÄpom.xml¡£È»ºó½«ServiceCall×é¼þÅäÖÃΪʹÓù²Ïí·¾¶¶¨ÒåÖеÄËùÓзþÎñµ÷ÓõÄKubernetesÖ÷½Úµã·¢ÏÖ£º
KubernetesConfiguration kubernetesConfiguration
=
new KubernetesConfiguration();
kubernetesConfiguration.setMasterUrl("https://192
.168.64.2:8443");
kubernetesConfiguration.setClientCertFile("/Users
/antongoncharov/.minikube/client.crt");
kubernetesConfiguration.setClientKeyFile("/Users
/antongoncharov/.minikube/client.key");
kubernetesConfiguration.setNamespace("default¡±);
ServiceCallConfigurationDefinition config =
new
ServiceCallConfigurationDefinition();
config.setServiceDiscovery(new KubernetesClientSe
rviceDiscovery(kubernetesCon
figuration));
context.setServiceCallConfiguration(config); |
ServiceCall EIPÍêÉÆÁËSpring Boot¡£´ó¶àÊýÑ¡Ïî¿ÉÒÔÖ±½ÓÔÚapplication.propertiesÎļþÖÐÅäÖá£
ʹÓÃServiceCall×é¼þÊÚȨCamel ·ÓÉ£º
rest("/orders")
.get("/").description("Get all
orders with details").outType(TestResponse.class)
.route()
.hystrix()
.setHeader("Content-Type", constant("application/json"))
.setHeader("Accept", constant("application/json"))
.setHeader(Exchange.HTTP_METHOD, constant("GET"))
.removeHeaders("CamelHttp*")
.serviceCall("customer-srv","http4:customer-deployment?bridgeEndpoint=true")
.unmarshal(formatOrder)
.enrich("direct:enrichFromInventory",
new OrderAggregationStrategy())
.to("log:result")
.endRest();
from("direct:enrichFromInventory")
.transform().simple("${null}")
.setHeader("Content-Type", constant("application/json"))
.setHeader("Accept", constant("application/json"))
.setHeader(Exchange.HTTP_METHOD, constant("GET"))
.removeHeaders("CamelHttp*")
.serviceCall("order-srv","http4:order-srv?bridgeEndpoint=true")
.unmarshal(formatInventory); |
ÎÒÃÇ»¹Æô¶¯ÁË·ÏßÖеĶÏ·Æ÷¡£ÕâÊÇÒ»¸ö¼¯³É¹Ò¹³£¬ÔÊÐíÔÚ·¢ËÍ´íÎó»òÊÕ¼þÈ˲»¿ÉÓõÄÇé¿öÏÂÔÝÍ£Ô¶³Ìϵͳµ÷Óá£ÕâÖ¼ÔÚ±ÜÃâ¼¶ÁªÏµÍ³¹ÊÕÏ¡£Hystrix×é¼þͨ¹ýʵÏÖ¶Ï·Æ÷ģʽÀ´°ïÖúʵÏÖÕâÒ»µã¡£
ÈÃÎÒÃÇÔËÐÐËü²¢·¢ËͲâÊÔÇëÇó; ÎÒÃÇ»áµÃµ½ÕâÁ½¸ö·þÎñ¾ÛºÏµÄÏìÓ¦¡£
[{"id":1,"items":[{"id":2,"name":"Monitor","description":"27-inch,
response time: 7ms","price":200 |
½á¹ûÈçÔ¤ÆÚ¡£
ÆäËûÓÃÀý
ÎÒչʾÁËApache CamelÈçºÎÔÚÒ»¸ö¼¯ÈºÖм¯³É΢·þÎñ¡£Õâ¸ö¿ò¼ÜµÄÆäËûÓÃ;ÊÇʲô£¿Ò»°ãÀ´Ëµ£¬ÔÚ»ùÓÚ¹æÔòµÄ·ÓÉ¿ÉÄÜÊǽâ¾ö·½°¸µÄÈκεط½¶¼ÊÇÓÐÓõġ£ÀýÈ磬Apache
Camel¿ÉÒÔ³ÉΪEclipse KuraÊÊÅäÆ÷µÄÎïÁªÍøÖмä¼þ¡£Ëü¿ÉÒÔ´¦ÀíÀ´×Ô¸÷ÖÖ×é¼þºÍ·þÎñµÄÈÕÖ¾ÐźŵļàÊÓ£¬¾ÍÏñÔÚCERNϵͳÖÐÒ»Ñù¡£ËüÒ²¿ÉÒÔÊÇÆóÒµ¼¶SOAµÄ¼¯³É¿ò¼Ü£¬Ò²¿ÉÒÔÊÇÅúÁ¿Êý¾Ý´¦ÀíµÄ¹ÜµÀ£¬ËäÈ»ËüÔÚÕâ·½ÃæÓëApache
SparkûÓкܺõľºÕù¡£
½áÂÛ
Äã¿ÉÒÔ¿´µ½ÏµÍ³¼¯³É²»ÊÇÒ»¸ö¼òµ¥µÄ¹ý³Ì¡£ÎÒÃǺÜÐÒÔË£¬ÒòΪÊÕ¼¯Á˺ܶà¾Ñé¡£ÕýÈ·Ó¦ÓÃËüÀ´¹¹½¨Áé»îºÍÈÝ´íµÄ½â¾ö·½°¸·Ç³£ÖØÒª¡£
ΪÁËÈ·±£ÕýÈ·µÄÓ¦Óã¬ÎÒ½¨ÒéÓÐÒ»¸öÖØÒªµÄ¼¯³É·½ÃæµÄÇåµ¥¡£±ØÐë¾ß±¸µÄÏîÄ¿°üÀ¨£º
1.ÊÇ·ñÓе¥¶ÀµÄ¼¯³É²ã£¿
2.ÊÇ·ñÓм¯³É²âÊÔ£¿
3.ÎÒÃÇÖªµÀÔ¤ÆÚµÄ·åÖµÊý¾ÝÇ¿¶ÈÂð£¿
4.ÎÒÃÇÊÇ·ñÖªµÀÔ¤ÆÚµÄÊý¾Ý½»¸¶Ê±¼ä£¿
5.ÏûÏ¢Ïà¹ØÐÔÊÇ·ñÖØÒª£¿Èç¹ûÐòÁÐÖжϣ¿
6.ÎÒÃÇÓ¦¸ÃÒÔͬ²½»¹ÊÇÒì²½µÄ·½Ê½À´×ö£¿
7.¸ñʽºÍ·ÓɹæÔò¸üƵ·±µØ±ä»¯ÔÚÄÄÀ
8.ÎÒÃÇÓа취¼à¶½Õâ¸ö¹ý³ÌÂð£¿
ÔÚ±¾ÎÄÖУ¬ÎÒÃdz¢ÊÔÁËApache Camel£¬ÕâÊÇÒ»¸öÇáÁ¿¼¶¼¯³É¿ò¼Ü£¬¿É°ïÖúÄúÔÚ½â¾ö¼¯³ÉÎÊÌâʱ½Úʡʱ¼äºÍ¾«Á¦¡£ÕýÈçÎÒÃÇËùչʾµÄ£¬Ëü¿ÉÒÔ×÷Ϊһ¸ö¹¤¾ß£¬Ö§³ÖÏà¹ØµÄ΢·þÎñÌåϵ½á¹¹£¬È«Ã渺Ôð΢·þÎñÖ®¼äµÄÊý¾Ý½»»»¡£ |