โพสต์บล็อกก่อนหน้านี้สร้างเฟรมเวิร์กยูเรก้า+ริบบิ้น+ฮิสทริกซ์ แม้ว่าโดยทั่วไปจะสามารถตอบสนองการโทรระหว่างบริการได้ แต่รหัสก็ดูน่าเกลียดจริงๆ ไคลเอนต์ต้องเขียน RestTemplate ทุกครั้ง เพื่อที่จะทำให้การโทรสวยงามและอ่านได้มากขึ้นตอนนี้เรากำลังเรียนรู้ที่จะใช้แสร้งทำเป็น
Feign รวมถึง Ribbon และ Hystrix ซึ่งค่อยๆประสบความสำคัญในการต่อสู้จริง การรวมที่เรียกว่าไม่ใช่การรวมทางกายภาพของแพ็คเกจขวดของ Feign รวมถึงแพ็คเกจ Jar ของ Ribbon และ Hystrix แต่การรวมตรรกะของฟังก์ชั่นของ Feign รวมถึงฟังก์ชั่นของอีกสองฟังก์ชั่น กล่าวโดยย่อ: Feign สามารถทำสิ่งต่าง ๆ เกี่ยวกับ Ribbon และ Hystrix ได้ แต่เพื่อใช้คำอธิบายประกอบที่นำโดย Ribbon และ Hystrix ต้องมีการแนะนำแพ็คเกจ JAR ที่สอดคล้องกัน
กรณีที่ 1:
ศูนย์ทะเบียนยูเรก้า: 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+Web ที่เรียบง่ายโดยให้วิธีการต่อไปนี้
@RestController @RequestMapping ("/feign-service") ชั้นเรียนสาธารณะ HelloServiceContorller {ส่วนตัว logger logger = loggerFactory.getLogger (this.getClass ()); โมฆะส่วนตัวการนอนหลับ (เมธอดสตริง) {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"); return "HelloServiceImpl ชื่อ:"+ชื่อ; } @RequestMapping (value = "/servicehead", method = requestmethod.head) สตริงสาธารณะ helloService (@requestheader ชื่อสตริง, @requestheader รหัสผ่านสตริง) {sleep ("header"); ส่งคืน "HelloServiceHhead Name:"+Name+"รหัสผ่าน:"+รหัสผ่าน; } @RequestMapping (value = "/servicePost", method = requestMethod.post) สตริงสาธารณะ helloService (@requestbody UserDemo UserDemo) {sleep ("post"); return userdemo.toString (); - คำอธิบายประกอบต่อไปนี้ที่ต้องให้ความสนใจไม่สามารถละเว้นได้
@RequestParam: คำอธิบายประกอบซึ่งระบุว่าพารามิเตอร์วิธีการควรถูกผูกไว้กับพารามิเตอร์การร้องขอเว็บ
@RequestBody: คำอธิบายประกอบการระบุวิธีการพารามิเตอร์ควรผูกพันกับเนื้อหาของการร้องขอเว็บ
@RequestHeader: คำอธิบายประกอบซึ่งระบุว่าพารามิเตอร์วิธีการควรถูกผูกไว้กับส่วนหัวคำขอเว็บ
หากคำอธิบายประกอบข้างต้นหายไปแม้ว่าบริการจะไม่รายงานข้อผิดพลาดหลังจากเรียกใช้ แต่ก็ไม่สามารถรับพารามิเตอร์รายการได้
โครงการโทรบริการ:
<การพึ่งพา> <roupId> org.springframework.cloud </groupId> <ratifactid> Spring-Cloud-Starter-Feign </artifactid>
Feign นั้นพึ่งพาได้ที่นี่ไม่ใช่ Ribbon และ Hystrix
Application.yml:
เซิร์ฟเวอร์: พอร์ต: 9051 สปริง: แอปพลิเคชัน: ชื่อ: demo-feign-freeconsumer Eureka: ไคลเอนต์: ServiceUrl: defaultZone: http: // peer1: 1111/eureka/, http: // peer2: 1112/eureka/feign
การกำหนดค่าของ Hystrix ทำให้ฉันหลอกเป็นเวลานาน สปริงคลาวด์ที่ฉันใช้คือ Dalston Version SR1 ซึ่งใหม่กว่าวัสดุอื่น ๆ บนอินเทอร์เน็ต เนื่องจากในเวอร์ชันใหม่การสนับสนุนของ Feign สำหรับ Hystrix จะถูกปิดโดยค่าเริ่มต้นดังนั้นคุณต้องเปิด Feign.hystrix.enabled = TRUE ผ่านการกำหนดค่าเพื่อให้บริการลดระดับและฟังก์ชั่นอื่น ๆ จะมีประสิทธิภาพ
โปรแกรมเริ่มต้นแอปพลิเคชัน
@springbootapplication @enableeurekaclient @enablefeignclients คลาสสาธารณะ demofeignapplication {โมฆะสาธารณะคงที่หลัก (สตริง [] args) {springapplication.run (demofeignapplication.class, args); - โปรดทราบว่ามีข้อผิดพลาดอื่นที่นี่ ฉันใช้ @springbootapplication+ @enableeurekaclient แทน @springcloudapplication เนื่องจากหลังมี @enablecircuitbreaker และ @enablecircuitbreaker เป็นเนื้อหาในแพ็คเกจ Hystrix ปอมของฉันไม่แนะนำ Hystrix ดังนั้นคลาวด์ฤดูใบไม้ผลิยังคงมีข้อบกพร่องในเรื่องนี้ คุณจะไม่รายงานข้อผิดพลาดโดยการรวบรวมโดยตรงด้วย @springcloudapplication แต่ไม่สามารถเริ่มต้นได้ แน่นอนตัวเอกที่นี่ยังคงเป็นคำอธิบายประกอบ @enablefeignclients
รหัสลูกค้าหลัก
@feignClient (name = "demo-feign-freeservice", fallback = demofeignfallback.class) อินเตอร์เฟสสาธารณะ demofeignservice {@requestmapping (value = "/feign-service/serviceget", method = requestmethod.get) สตริง helloservice (@requestparam ("ชื่อ") @RequestMapping (value = "/feign-service/servicehead", method = requestmethod.head) สตริง helloService (@requestheader ("ชื่อ") ชื่อสตริง, @requestheader ("รหัสผ่าน") รหัสผ่านสตริง); @RequestMapping (value = "/feign-service/servicePost", method = requestMethod.post) สตริง helloService (@requestbody userDemo UserDemo); - คำอธิบายประกอบ @feignclient กำหนดว่าอินเทอร์เฟซเป็นไคลเอ็นต์ปลอมชื่อระบุชื่อบริการที่ลงทะเบียนบนยูเรก้าและทางเลือกเป็นคลาสการใช้งานอินเตอร์เฟสหลังจากที่บริการถูกปรับลดลง
@RequestMapping ระบุ URL ที่สัมพันธ์กันและวิธีการร้องขอ HTTP ของคำขอซึ่งสอดคล้องกับเซิร์ฟเวอร์ทีละตัว @requestparam
@requestbody และ @requestheader คำอธิบายประกอบมีคุณลักษณะที่มีค่ามากกว่าเซิร์ฟเวอร์ พวกเขาไม่สามารถละเว้นได้ที่นี่ พวกเขาจำเป็นต้องแจ้งให้ลูกค้าแสวงหาอย่างชัดเจนเกี่ยวกับวิธีการสอดคล้องกับพารามิเตอร์
รหัสบริการปรับลดลง:
@component คลาสสาธารณะ Demofeignfallback ใช้ demofeignservice {@Override สตริงสาธารณะ HelloService (ชื่อสตริง) {return "รับข้อผิดพลาด"; } @Override สตริงสาธารณะ HelloService (ชื่อสตริง, รหัสผ่านสตริง) {return "head error"; } @Override สตริงสาธารณะ HelloService (UserDemo UserDemo) {return "Post Error"; - ฉันพบว่าฉันตั้งใจลบ @requestparam, @requestbody และ @requestheader คำอธิบายประกอบในพารามิเตอร์รายการที่นี่เพราะความสำคัญที่สำคัญของคำอธิบายประกอบเหล่านี้คือการแสร้งทำเพื่อส่งพารามิเตอร์ไปยัง HTTP เมื่อทำการโทร microservice
รหัสคอนโทรลเลอร์:
@RestController คลาสสาธารณะ DemofeignController {@autowired ส่วนตัว demofeignservice demofeignservice; @RequestMapping (value = "/test", method = requestMethod.get) DemoserviceTest String สาธารณะ () {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 วิธีการ หัวไม่คืนร่างกายของการตอบสนองและโดยทั่วไปจะใช้สำหรับการทดสอบการเชื่อมต่อ
มาดูชุดอื่น:
วิธีการขอศีรษะและโพสต์ได้รับการประมวลผลมานานกว่า 2,000 มม. และบริการจะถูกปรับลดลงและการใช้งานจะถูกแทนที่ด้วยคลาสการประมวลผลทางเลือก
ในกรณีที่หนึ่งเรามักจะรู้สึกว่ามีรหัสซ้ำระหว่างผู้ให้บริการและผู้โทรบริการ สามารถปรับให้เหมาะสมได้หรือไม่? โปรดดูกรณีที่ 2
กรณีที่ 2:
ศูนย์ทะเบียนยูเรก้า: https://github.com/yejingtao/forblog/tree/master/demo-eureka-register
อินเตอร์เฟส API: https://github.com/yejingtao/forblog/tree/master/demo-feign-serviceapi
ผู้ให้บริการ: 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) สตริง HelloService (@requestparam ("ชื่อ") ชื่อสตริง); @RequestMapping (value = "/feign-service/servicehead", method = requestmethod.head) สตริง helloService (@requestheader ("ชื่อ") ชื่อสตริง, @requestheader ("รหัสผ่าน") รหัสผ่านสตริง); @RequestMapping (value = "/feign-service/servicePost", method = requestMethod.post) สตริง helloService (@requestbody userDemo UserDemo); - ผู้ให้บริการ:
@RestController คลาสสาธารณะ HelloServiceContorller ใช้ HelloService {Private Logger Logger = LoggerFactory.getLogger (this.getClass ()); โมฆะส่วนตัวการนอนหลับ (เมธอดสตริง) {int sleepmintime = new random (). NextInt (3000); logger.info ("HelloService"+MethodName+"SleepMintime:"+SleepMintime); ลอง {thread.sleep (Sleepmintime); } catch (interruptedException e) {e.printStackTrace (); }} @Override สตริงสาธารณะ HelloService (@requestparam ("ชื่อ") ชื่อสตริง) {sleep ("get"); return "HelloServiceImpl ชื่อ:"+ชื่อ; } @Override สตริงสาธารณะ HelloService (@requestheader ("ชื่อ") ชื่อสตริง, @requestheader ("รหัสผ่าน") รหัสผ่านสตริง) {sleep ("header"); ส่งคืน "HelloServiceHhead Name:"+Name+"รหัสผ่าน:"+รหัสผ่าน; } @Override สตริงสาธารณะ HelloService (@requestbody UserDemo UserDemo) {sleep ("post"); return userdemo.toString (); - ผู้โทรบริการ:
@feignClient (name = "demo-feign-serviceimpl", fallback = feignservicefallback.class) ส่วนต่อประสานสาธารณะ FeignService ขยาย HelloService {}รหัสอื่น ๆ ยังคงไม่เปลี่ยนแปลงและเอฟเฟกต์ก็เหมือนกัน
ทั้งสองรูปแบบมีข้อดีและข้อเสียของตัวเอง: ฟรีสไตล์ฟรีมากขึ้นและวิธีการใหม่ที่เพิ่มลงในเซิร์ฟเวอร์จะไม่ส่งผลกระทบต่อรหัสไคลเอ็นต์ ข้อเสียคือความสามารถในการให้บริการไม่ได้ซิงโครไนซ์และการเปลี่ยนแปลงความสามารถในการให้บริการจะทำให้เกิดความผิดปกติ ความสามารถในการให้บริการไคลเอ็นต์ของเซิร์ฟเวอร์ API นั้นถูกซิงโครไนซ์ แต่การเปลี่ยนแปลงในอินเตอร์เฟสจำเป็นต้องมีการปรับเปลี่ยนรหัสทั้งสองด้านและคุณต้องพิจารณาอย่างชัดเจนเมื่อสร้าง
ข้างต้นเป็นเนื้อหาทั้งหมดของบทความนี้ ฉันหวังว่ามันจะเป็นประโยชน์ต่อการเรียนรู้ของทุกคนและฉันหวังว่าทุกคนจะสนับสนุน wulin.com มากขึ้น