이전 블로그 게시물은 Eureka+Ribbon+Hystrix 프레임 워크를 구축했습니다. 기본적으로 서비스 간의 통화를 충족시킬 수 있지만 코드는 정말 추악 해 보입니다. 클라이언트는 매번 resttemplate를 작성해야합니다. 우리는 전화를 더 아름답고 읽을 수 있도록하기 위해 이제는 Feign을 사용하는 법을 배우고 있습니다.
Feign에는 리본과 히스트릭스가 포함되어 있으며, 실제 전투에서 점차적으로 중요성을 경험하고 있습니다. 소위 포함은 리본 및 Hystrix의 JAR 패키지를 포함한 Feign의 JAR 패키지를 물리적으로 포함시키는 것이 아니라 다른 두 가지 기능을 포함하여 Feign 기능의 논리적 포함입니다. 요컨대 : Feign은 리본과 hystrix에 대해 일을 할 수 있지만 리본과 hystrix로 가져온 주석을 사용하려면 해당 JAR 패키지를 도입해야합니다.
Case 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+웹 응용 프로그램으로 다음 방법을 제공합니다.
@RestController @requestmapping ( "/feign-service") 공개 클래스 HelloServiceContorller {private logger = loggerfactory.getLogger (this.getClass ()); 개인 void sleep (String MethodName) {int sleepmintime = new random (). NextInt (3000); logger.info ( "HelloService"+MethodName+"SleepMintime :"+sleepmintime); try {thread.sleep (sleepmintime); } catch (InterruptedException e) {e.printstacktrace (); }} @requestmapping (value = "/serviceget", method = requestmethod.get) public String helloService (@requestparam 문자열 이름) {sleep ( "get"); 반환 "HelloServiceImpl 이름 :"+이름; } @requestmapping (value = "/servicehead", method = requestMethod.head) public String helloService (@requestheader 문자열 이름, @requestheader string password) {sleep ( "header"); "HelloServicehead 이름 :"+name+"password :"+password; } @requestMapping (value = "/servicePost", method = requestMethod.post) public String helloService (@requestbody userDemo userDemo) {sleep ( "post"); return userDemo.toString (); }} 주의를 기울여야하는 다음 주석은 생략 할 수 없습니다.
@RequestParam : 메소드 매개 변수가 웹 요청 매개 변수에 바인딩되어야 함을 나타내는 주석
@RequestBody : MethodParameter를 나타내는 주석은 웹 요청의 본문에 묶여 있어야합니다.
@requestheader : 메소드 매개 변수가 웹 요청 헤더에 바인딩되어야 함을 나타내는 주석.
위의 주석이 누락 된 경우 서비스가 실행 된 후 오류를보고하지 않지만 항목 매개 변수를 얻을 수 없습니다.
서비스 발신자 프로젝트 :
<pectionency> <groupid> org.springframework.cloud </groupid> <artifactid> Spring-Cloud-Starter-Feign </artifactid> </fectionency>
Feign은 리본과 hystrix가 아니라 여기에만 의존합니다.
application.yml :
서버 : 9051 스프링 : 응용 프로그램 : 이름 : 이름 : Demo-Feign-Freeconsumer Eureka : Client : ServiceUrl : http : // peer1 : 1111/eureka/, http : // peer2 : 1112/eureka/feign : hystrix : enabled : # # # # # # # # # # # # # 300.
Hystrix의 구성은 오랫동안 저를 속였습니다. 내가 사용한 스프링 클라우드는 Dalston 버전 SR1이며 인터넷의 다른 자료 버전보다 새롭습니다. 새 버전에서는 Feign의 Hystrix에 대한 지원이 기본적으로 꺼져 있으므로 구성을 통해 Feign.hystrix.enabled = true를 수동으로 켜야합니다. 서비스 다운 그레이드 및 기타 기능이 효과적입니다.
응용 프로그램 스타터 프로그램
@SpringBootApplication @enableEureKAclient @enableFeignClients Public Class DemofeignApplication {public static void main (String [] args) {springApplication.run (demofeignApplication.class, argss); }} 여기에는 또 다른 함정이 있습니다. @SpringCloudApplication 대신 @SpringBootApplication+ @enableEureKaclient를 사용하고 있습니다. 후자에는 @EnableCircuitBreaker가 포함되어 있으며 @EnableCircuitBreaker는 HyStrix 패키지의 내용입니다. 내 POM은 Hystrix를 소개하지 않습니다. 따라서 스프링 클라우드는 여전히 이와 관련하여 단점이 있습니다. @SpringCloudApplication으로 직접 컴파일하여 오류를보고하지 않지만 시작할 수는 없습니다. 물론 여기의 주인공은 여전히 주석 @enablefeignclients입니다.
핵심 클라이언트 코드
@FeignClient (이름 = "Demo-Feign-Freeservice", Fallback = demofeignfallback.class) public 인터페이스 Demofeignservice {@requestmapping (value = "/feign-service/serviceget", method = requestmethod.get) String HelloService (@requestparam ( "name") String Name); @requestmapping (value = "/feign-service/servicehead", method = requestmethod.head) 문자열 helloService (@requestheader ( "name") 문자열 이름, @requestheader ( "password") 문자열 암호); @requestmapping (value = "/feign-service/servicepost", method = requestmethod.post) 문자열 helloService (@requestbody userDemo userDemo); } @feignclient 주석은 인터페이스가 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 (문자열 이름, 문자열 암호) {return "head error"; } @override public string helloService (userDemo userDemo) {return "post error"; }} Entry Parameters에서 @requestparam, @requestbody 및 @requestheader 주석을 의도적으로 제거한 것을 발견했습니다. 이러한 주석의 필수 중요성은 MicroService 호출을 할 때 매개 변수를 HTTP로 전달하는 데 사용되는 사용이지만 서비스 다운 그레이드는 HTTP 요청을 전혀하지 않기 때문에 여기에서 생략 할 수 있습니다.
컨트롤러 코드 :
@RestController Public Class DemofeignController {@autowired Private Demofeignservice Demofeignservice; @requestmapping (value = "/test", method = requestmethod.get) public String 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 (new userdemo ( "yejingtao", "123456"))); 반환 sb.toString (); }}효과를 보자 :
우리의 서비스는 시간이 걸리지 않았고 세 가지 방법 모두 정상 이었지만 헤드 요청은 반환 값을 얻지 못했습니다. 이것은 헤드 메소드 HTTP 요청의 특성에 의해 결정됩니다. 헤드는 응답의 신체를 반환하지 않으며 일반적으로 연결 테스트에 사용됩니다.
다른 세트를 살펴 보겠습니다.
헤드 및 포스트 요청 방법은 2000ms 이상으로 처리되었으며 서비스가 다운 그레이드되고 구현은 폴백 처리 클래스로 대체됩니다.
경우, 우리는 항상 서비스 제공 업체와 서비스 발신자 사이에 중복 코드가 있다는 느낌이 있습니다. 최적화 할 수 있습니까? 사례 2를 참조하십시오.
Case 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 ( "name") 문자열 이름); @requestmapping (value = "/feign-service/servicehead", method = requestmethod.head) 문자열 helloService (@requestheader ( "name") 문자열 이름, @requestheader ( "password") 문자열 암호); @requestmapping (value = "/feign-service/servicepost", method = requestmethod.post) 문자열 helloService (@requestbody userDemo userDemo); } 서비스 제공 업체 :
@RestController Public Class HelloServiceContorller HelloService {private logger = loggerfactory.getLogger (this.getClass ()); 개인 void sleep (String MethodName) {int sleepmintime = new random (). NextInt (3000); logger.info ( "HelloService"+MethodName+"SleepMintime :"+sleepmintime); try {thread.sleep (sleepmintime); } catch (InterruptedException e) {e.printstacktrace (); }} @override public String helloService (@requestparam ( "name") 문자열 이름) {sleep ( "get"); 반환 "HelloServiceImpl 이름 :"+이름; } @override public String helloService (@requestheader ( "name") 문자열 이름, @requestheader ( "password") 문자열 암호) {sleep ( "header"); "HelloServicehead 이름 :"+name+"password :"+password; } @override public String helloService (@requestbody userDemo userDemo) {sleep ( "post"); return userDemo.toString (); }} 서비스 발신자 :
@feignclient (name = "demo-feign-serviceimpl", fallback = feignservicefallback.class) public interface feignservice 확장 helloService {}다른 코드는 기본적으로 변경되지 않으며 효과는 동일합니다.
두 가지 스타일에는 고유 한 장점과 단점이 있습니다. 프리 스타일은 더 무료이며 서버에 추가 된 새로운 방법은 클라이언트 코드에 영향을 미치지 않습니다. 단점은 서비스 기능이 동기화되지 않고 서비스 기능의 변화가 이상을 유발한다는 것입니다. API 형식 서버 클라이언트 서비스 기능은 동기화되지만 인터페이스의 변경 사항은 양쪽에서 코드를 수정해야하며 빌드 할 때 명확하게 고려해야합니다.
위는이 기사의 모든 내용입니다. 모든 사람의 학습에 도움이되기를 바랍니다. 모든 사람이 wulin.com을 더 지원하기를 바랍니다.