I have two different micro services with eureka as service registry and now I am trying to call a micro service from another, resolving the endpoint with ribbon for client side load balancing.
Service A:
This service exposes an endpoint, http://localhost:15000/api/user/{userId}
, and the application.yml is as follows,
# Spring properties
spring:
application:
name: user_microservice
cloud:
config:
discovery:
enabled: false
# HTTP Server
server:
port: 15000 # HTTP (Tomcat) port
# Discovery Server Access
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
instance:
instanceId: ${spring.application.name}:${random.int}
metadataMap:
instanceId: ${spring.application.name}:${random.int}
logging:
level:
com.netflix.discovery: 'OFF'
org.springframework.cloud: 'DEBUG'
Service B which calls Service A, has the following Application class:
@EnableDiscoveryClient
@SpringBootApplication
public class UserSummaryApplication {
public static void main(String[] args) {
SpringApplication.run(UserSummaryApplication.class, args);
}
@Bean(name = "restTemplate")
RestTemplate restTemplate() {
return new RestTemplate();
}
@Bean(name = "loadBalancedRestTemplate")
@LoadBalanced
RestTemplate loadBalancedRestTemplate() {
return new RestTemplate();
}
}
Controller
@RestController
@RequestMapping("/api/usersummary")
public class UserSummaryController {
@Autowired
private UserSummaryService userSummaryService;
@RequestMapping(value="/{userId}", method= RequestMethod.GET)
@ResponseStatus(HttpStatus.OK)
public UserSummary getUserSummary(@PathVariable String userId){
return userSummaryService.getUserSummary(userId);
}
}
Service
@Service
public class UserSummaryService {
// Uses Ribbon to load balance requests
private RestTemplate loadBalancedRestTemplate;
public UserSummary getUserSummary(String UserId){
String url = String.format("http://%s%s","user_microservice","/api/user/{userId}");
logger.info(url);
try {
return this.loadBalancedRestTemplate.getForObject(url,
User.class, UserId).toString();
}catch (Exception e){
e.printStackTrace();
return null;
}
}
@Autowired
public void setLoadBalancedRestTemplate(RestTemplate loadBalancedRestTemplate) {
this.loadBalancedRestTemplate = loadBalancedRestTemplate;
}
}
But I getting an exception when I am trying to access the service:
java.lang.IllegalStateException: Request URI does not contain a valid hostname: http://user_microservice/api/user/599f877c8e365c0001cec8d1
usersummary_microservice_1 | at org.springframework.util.Assert.state(Assert.java:70)
usersummary_microservice_1 | at org.springframework.cloud.client.loadbalancer.LoadBalancerInterceptor.intercept(LoadBalancerInterceptor.java:54)
usersummary_microservice_1 | at org.springframework.http.client.InterceptingClientHttpRequest$InterceptingRequestExecution.execute(InterceptingClientHttpRequest.java:86)
usersummary_microservice_1 | at org.springframework.http.client.InterceptingClientHttpRequest.executeInternal(InterceptingClientHttpRequest.java:70)
usersummary_microservice_1 | at org.springframework.http.client.AbstractBufferingClientHttpRequest.executeInternal(AbstractBufferingClientHttpRequest.java:48)
usersummary_microservice_1 | at org.springframework.http.client.AbstractClientHttpRequest.execute(AbstractClientHttpRequest.java:53)
usersummary_microservice_1 | at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:652)
usersummary_microservice_1 | at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:613)
usersummary_microservice_1 | at org.springframework.web.client.RestTemplate.getForObject(RestTemplate.java:287)
usersummary_microservice_1 | at com.haulmatic.usersummary.service.userSummaryService.getuserSummary(UserSummaryService.java:33)
usersummary_microservice_1 | at com.haulmatic.usersummary.controller.userSummaryController.getuserSummary(UserSummaryController.java:29)
usersummary_microservice_1 | at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
usersummary_microservice_1 | at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
usersummary_microservice_1 | at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
usersummary_microservice_1 | at java.lang.reflect.Method.invoke(Method.java:498)
usersummary_microservice_1 | at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)
usersummary_microservice_1 | at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:133)
usersummary_microservice_1 | at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:97)
usersummary_microservice_1 | at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827)
usersummary_microservice_1 | at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738)
usersummary_microservice_1 | at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
usersummary_microservice_1 | at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:967)
usersummary_microservice_1 | at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:901)
usersummary_microservice_1 | at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
usersummary_microservice_1 | at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)
usersummary_microservice_1 | at javax.servlet.http.HttpServlet.service(HttpServlet.java:635)
usersummary_microservice_1 | at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
usersummary_microservice_1 | at javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
usersummary_microservice_1 | at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
usersummary_microservice_1 | at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
usersummary_microservice_1 | at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
usersummary_microservice_1 | at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
usersummary_microservice_1 | at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
usersummary_microservice_1 | at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197)
usersummary_microservice_1 | at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
usersummary_microservice_1 | at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
usersummary_microservice_1 | at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
usersummary_microservice_1 | at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)
usersummary_microservice_1 | at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
usersummary_microservice_1 | at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:478)
usersummary_microservice_1 | at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
usersummary_microservice_1 | at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:80)
usersummary_microservice_1 | at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
usersummary_microservice_1 | at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
usersummary_microservice_1 | at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:799)
usersummary_microservice_1 | at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
usersummary_microservice_1 | at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868)
usersummary_microservice_1 | at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1455)
usersummary_microservice_1 | at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
usersummary_microservice_1 | at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
usersummary_microservice_1 | at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
usersummary_microservice_1 | at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
usersummary_microservice_1 | at java.lang.Thread.run(Thread.java:748)
Any pointers on this?
You might use any protocol to communicate and propagate data asynchronously across microservices in order to have eventual consistency. As mentioned, you could use integration events using an event bus or message broker or you could even use HTTP by polling the other services instead.
Communication within a microservices system You can achieve this in your system by taking advantage of the following: Service calls, either synchronous or asynchronous (streaming), allow services to communicate with each other using published APIs and standard protocols (HTTP and WebSockets).
Containers are an excellent example of microservices architecture as they allow businesses to focus on developing services without worrying about dependencies. Cloud-native applications are commonly built as microservices by leveraging containers.
Underscore(_
) is invalid in a host name. Name your services with dashes (-
).
new URI("http://user_microservice/stuff").getHost() // null
new URI("http://user-microservice/stuff").getHost() // user-microservice
So change spring.application.name
to user-microservice
and change the URL in the client.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With