صمم منشور المدونة السابق إطار عمل Eureka+Ribbon+Hystrix. على الرغم من أنه يمكن أن يلبي المكالمات بين الخدمات بشكل أساسي ، إلا أن الرمز يبدو قبيحًا حقًا. يتعين على العميل كتابة repttemplate في كل مرة. من أجل إجراء المكالمات أكثر جمالًا وقابلة للقراءة ، نتعلم الآن استخدام Feign.
يتضمن Feign Ribbon و Hystrix ، الذي يعاني تدريجياً من أهميته في القتال الفعلي. إن ما يسمى بالتضمين ليس هو التضمين المادي لحزم جرة Feign بما في ذلك حزم Jartrix و Hystrix ، ولكن التضمين المنطقي لوظائف Feign بما في ذلك وظائف الاثنين الآخرين. باختصار: يمكن أن تفعل Feign أشياء حول الشريط والهستريكت ، ولكن لاستخدام التعليقات التوضيحية التي جلبتها Ribbon و Hystrix ، يجب تقديم حزمة الجرة المقابلة.
الحالة 1:
مركز تسجيل Eureka: https://github.com/yejingtao/forblog/tree/master/demo-eureka-register
مزود الخدمة: https://github.com/yejingtao/forblog/tree/master/demo-feign-freeservice
متصل الخدمة: https://github.com/yejingtao/forblog/tree/master/demo-feign-freeconsumer
مزود الخدمة هو تطبيق ويب eurekaclient+بسيط ، ويوفر الطرق التالية
RestController @REquestMapping ("/feign-service") الفئة العامة HelloServicEcontorller {private logger logger = loggerfactory.getLogger (this.getClass ()) ؛ private void sleep (String methodName) {int sleepmintime = new Random (). nextInt (3000) ؛ logger.info ("HelloService"+MethodName+"SleepMintime:"+SleepMintime) ؛ جرب {thread.sleep (SleepMintime) ؛ } catch (interruptedException e) {E.PrintStackTrace () ؛ }} @requestmapping (value = "/serviceget" ، method = requestMethod.get) السلسلة العامة HelloService (اسم سلسلة requestparam) {sleep ("get") ؛ إرجاع "HelloServiceImpl Name:"+name ؛ } @requestmapping (value = "/servicehead" ، method = requestMethod.head) السلسلة العامة HelloService (اسم سلسلة requestheader ، كلمة مرور requestheader string) {sleep ("header") ؛ إرجاع "HelloServicehead Name:"+name+"كلمة المرور:"+كلمة المرور ؛ } @requestmapping (value = "/servicePost" ، method = requestMethod.post) السلسلة العامة HelloService (requestbody userDemo userDemo) {sleep ("post") ؛ إرجاع userDemo.toString () ؛ }} لا يمكن حذف التعليقات التوضيحية التالية التي يجب إيلاء الاهتمام بها.
requestparam: التعليق التوضيحي الذي يشير إلى أن معلمة الطريقة يجب أن تكون مرتبطة بمعلمة طلب الويب
@REQUESTBODY: يجب أن يكون التعليق التوضيحي يشير إلى أن methodparameter مرتبطًا بجسم طلب الويب.
REQUESTHEADER: التعليق التوضيحي الذي يشير إلى أن معلمة الطريقة يجب أن تكون مرتبطة برأس طلب الويب.
إذا كانت التعليقات التوضيحية المذكورة أعلاه مفقودة ، على الرغم من أن الخدمة لن تبلغ عن خطأ بعد تشغيلها ، فلن تتمكن من الحصول على معلمات الدخول.
مشروع المتصل بالخدمة:
<Rependency> <rouper> org.springframework.cloud </groupId> <intifactid> spring-cloud-starter-feign </artifactid> </premed>
يعتمد Feign فقط هنا ، وليس الشريط و Hystrix.
application.yml:
الخادم: المنفذ: 9051 الربيع: التطبيق: الاسم: demo-feign-freeconsumer eureka: العميل: Serviceurl: DefaultZone: http: // peer1: 1111/eureka/، http: // peer2: 1112/eureka/feign: hystrix: actornd: true #ribbon setting # ribbon:
لقد خدعني تكوين Hystrix لفترة طويلة. سحابة الربيع التي استخدمتها هي إصدار Dalston SR1 ، وهو أحدث من إصدارات المواد الأخرى على الإنترنت. لأنه في الإصدار الجديد ، يتم إيقاف دعم Feign لـ Hystrix بشكل افتراضي ، لذلك يجب عليك تشغيل Feign.Hystrix.Endabled = True من خلال التكوين ، بحيث تكون خفض الخدمة والوظائف الأخرى فعالة.
برنامج بداية التطبيق
springBOOTAPPLICATION enableeurekaclient enablefeignclients الفئة العامة demofeignapplication {public static void main (string [] args) {springapplication.run (demofeignapplication.class ، args) ؛ }} لاحظ أن هناك مأزق آخر هنا. أنا أستخدم @springbootapplication+ @enableeurekaclient بدلاً من springCloudapPlication ، لأن الأخير يحتوي على enableCircuitBreaker ، و enableCircuitBreaker هو المحتوى في حزمة Hystrix. بلدي بوم لا يقدم Hystrix. لذلك لا يزال لدى الربيع السحابة أوجه القصور في هذا الصدد. لن تقوم بالإبلاغ عن خطأ من خلال التجميع مباشرة باستخدام springCloudapPlication ، ولكن لا يمكن أن يبدأ. بالطبع ، لا يزال بطل الرواية هنا التعليق التوضيحي enablefeignclients.
رمز العميل الأساسي
feignclient (name = "demo-feign-freeservice" ، fardback = demofeignfallback.class) الواجهة العامة demofeignservice {REquestMapping (value = "/feign-service/servicetget" ، method = requestMethod.get) String HelloService (requestparam ("name") requestmapping (value = "/feign-service/servicehead" ، method = requestMethod.head) string helloService ( @requestheader ("name") اسم السلسلة ، requestheader ("كلمة المرور") سلسلة كلمة مرور السلسلة) ؛ requestmapping (value = "/feign-service/servicePost" ، method = requestMethod.post) string helloService (erseestbody userDemo userDemo) ؛ } يعرّف شرح @VIGNCLIENT أن الواجهة هي عميل FEIGN ، ويحدد الاسم اسم الخدمة المسجل على EUREKA ، والتراجع هو فئة تنفيذ الواجهة بعد تخفيض الخدمة.
يحدد REquestMapping طرق طلب عنوان URL و HTTP النسبي للطلب ، والذي يتوافق مع الخادم واحدًا تلو الآخر. requestparam ،
requestbody و requestheader التعليقات التوضيحية لها سمات قيمة أكثر من الخوادم. لا يمكن حذفها هنا. إنهم بحاجة إلى إبلاغ عميل Feign بشكل صريح كيفية التوافق مع المعلمات.
رمز الخدمة خفض:
component public class demofeignfallback تنفذ demofeignservice {Override public string helloService (اسم السلسلة) {return "get error" ؛ } Override public string helloService (اسم السلسلة ، كلمة مرور السلسلة) {إرجاع "خطأ الرأس" ؛ } Override public string HelloService (userDemo userDemo) {return "post error" ؛ }} لقد وجدت أنني أزلت عن عمد requestparam و @requestbody و requestHeader التعليقات التوضيحية في معلمات الدخول هنا ، لأن الأهمية الأساسية لهذه التعليقات التوضيحية هي أن التظاهر يستخدم لتمرير المعلمات إلى HTTP عند إجراء مكالمات الخدمات الصغيرة ، ولكن لن يؤدي تراجع الخدمة إلى طلبات HTTP في جميع أنحاء ، لذلك يمكن أن تكون موجودة هنا.
رمز وحدة التحكم:
RestController الفئة العامة demofeigntroller {autowired private demofeignservice demofeignservice ؛ requestmapping (value = "/test" ، method = requestMethod.get) السلسلة العامة demoServIcEtest () {StringBuffer sb = new StringBuffer () ؛ sb.append (demofeignservice.helloservice ("Yuanyuan")) ؛ sb.append ("/n") ؛ sb.append (demofeignservice.helloservice ("yjt" ، "xixihaha")) ؛ sb.append ("/n") ؛ sb.append (demofeignservice.helloservice (userDemo جديد ("yejingtao" ، "123456"))) ؛ إرجاع sb.tostring () ؛ }}دعونا نرى التأثير:
لم تتم خدمتنا ، كانت جميع الطرق الثلاثة طبيعية ، لكن طلب الرأس لم يحصل على قيمة الإرجاع. يتم تحديد ذلك من خلال خصائص طلب HTTP طريقة الرأس. لا يعيد الرأس جسم الاستجابة ، ويستخدم بشكل عام لاختبار الاتصال.
دعونا نلقي نظرة على مجموعة أخرى:
تمت معالجة أساليب الطلب والمنصب لأكثر من 2000 مللي ثانية ، ويتم تخفيض الخدمة ، ويتم استبدال التنفيذ بفئة معالجة الاحتياطية.
في حالة واحدة ، لدينا دائمًا شعور بأن هناك رمزًا مكررًا بين مزود الخدمة ومتصل الخدمة. هل يمكن تحسينه؟ يرجى الاطلاع على الحالة 2.
الحالة 2:
مركز تسجيل Eureka: https://github.com/yejingtao/forblog/tree/master/demo-eureka-register
واجهة API: https://github.com/yejingtao/forblog/tree/master/demo-feign-servicapi
مزود الخدمة: https://github.com/yejingtao/forblog/tree/master/demo-feign-serviceimpl
متصل الخدمة: https://github.com/yejingtao/forblog/tree/master/demo-feign-apicconsumer
أكبر تغيير في الحالة 2 هو كتابة قدرات الخدمة بشكل منفصل في مشروع API ، ويعتمد كل من المتصل والمزود POM على API هذا.
API:
الواجهة العامة HelloService {REquestMapping (value = "/feign-service/serviceget" ، method = requestMethod.get) string helloService ( @requestparam ("name") اسم السلسلة) ؛ requestmapping (value = "/feign-service/servicehead" ، method = requestMethod.head) string helloService ( @requestheader ("name") اسم السلسلة ، requestheader ("كلمة المرور") سلسلة كلمة مرور السلسلة) ؛ requestmapping (value = "/feign-service/servicePost" ، method = requestMethod.post) string helloService (erseestbody userDemo userDemo) ؛ } مزود الخدمة:
RestController public class HelloServicEcontorller تنفذ HelloService {private logger logger = loggerfactory.getLogger (this.getClass ()) ؛ private void sleep (String methodName) {int sleepmintime = new Random (). nextInt (3000) ؛ logger.info ("HelloService"+MethodName+"SleepMintime:"+SleepMintime) ؛ جرب {thread.sleep (SleepMintime) ؛ } catch (interruptedException e) {E.PrintStackTrace () ؛ }} Override public string helloService (requestparam ("name") اسم السلسلة) {sleep ("get") ؛ إرجاع "HelloServiceImpl Name:"+name ؛ } Override public string helloService (requestHeader ("name") اسم السلسلة ، requestHeader ("password") سلسلة كلمة مرور) {sleep ("header") ؛ إرجاع "HelloServicehead Name:"+name+"كلمة المرور:"+كلمة المرور ؛ } Override public string helloService (requestbody userDemo userDemo) {sleep ("post") ؛ إرجاع userDemo.toString () ؛ }} متصل الخدمة:
feignclient (name = "Demo-Feign-ServiceImpl" ، FackBack = FeignServiceFallback.class) واجهة عامة FeignService تمتد HelloService {}لا تزال الرموز الأخرى دون تغيير ، والتأثير هو نفسه.
الأسلوبان لهما مزاياه وعيوبهما: Freestyle أكثر حرية ، ولن تؤثر الطريقة الجديدة التي تمت إضافتها إلى الخادم على رمز العميل. العيب هو أن قدرات الخدمة لا تتم مزامنتها وأن التغييرات في قدرات الخدمة ستؤدي إلى تشوهات ؛ تتم مزامنة إمكانات خدمة عميل خادم API لتنسيق ، لكن التغييرات في الواجهة تتطلب تعديل الرمز على كلا الجانبين ، ويجب أن تفكر بوضوح عند بنائها.
ما سبق هو كل محتوى هذه المقالة. آمل أن يكون ذلك مفيدًا لتعلم الجميع وآمل أن يدعم الجميع wulin.com أكثر.