While I am trying to reach the service meeting
via Zuul gateway, Zuul is unable to forward the request to the respective service. The following errors are what I am facing:
- nettflix.zuul.exception.ZuulException: Forwarding error
- Caused by: com.netflix.client.ClientException: Load balancer does not have available server for client: meeting
Let me share the application.yml for the service, eureka and zuul gateway.
EurekaClient:
Application.yml
server:
port: 8761
eureka:
instance:
hostname: localhost
lease-renewal-interval-in-seconds: 300
client:
register-with-eureka: false
fetch-registry: true
serviceUrl:
defaultZone: http://localhost:8761/eureka/
ZuulGateWay:
application.yml
server:
port: 8085
spring:
application:
name: gatekeeper
zuul:
routes:
meeting: /meeting/**
serviceId: meeting
ribbon:
eureka:
enabled: false
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
ZuulGateWay: SpringBootApplication
package com.sagarp.gatekeeper;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
@SpringBootApplication
@EnableEurekaClient
@EnableZuulProxy
public class MeetingApplication {
public static void main(String[] args) {
SpringApplication.run(MeetingApplication.class, args);
}
}
My Service class (meeting): Application.yml
server:
port: 0
spring:
application:
name: meeting
datasource:
url: jdbc:mysql://localhost:3306/sagarp?useSSL=false
username: myUserName
password: myPassWord
jpa:
properties:
hibernate:
dialect: org.hibernate.dialect.MySQL5InnoDBDialect
hibernate:
ddl-auto: update
eureka:
client:
registerWithEureka: true
fetchRegistry: true
serviceUrl:
defaultZone: http://localhost:8761/eureka/
instance:
lease-renewal-interval-in-seconds: 5
My Service class (meeting): SpringBootApplication
package com.sagarp;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
@SpringBootApplication
@EnableEurekaClient
public class MeetingApplication {
public static void main(String[] args) {
SpringApplication.run(MeetingApplication.class, args);
}
}
As you can see, the configuration ensures that all my services are discovered by eureka client.
In the eureka console, I have verified the same, the zuul gateway
and my service(meeting)
both are visible.
For better view, you can visit my git repo. https://github.com/sagar-patro/demo-microservices
Any help would be very much appreciable
Problem: The problem of server side load balancing is if one or more servers stop responding, we have to manually remove those servers from the load balancer by updating the IP table of the load balancer. Another problem is that we have to implement a failover policy to provide the client with a seamless experience.
It's pointless to load balance a single server. What load balancing does is decide which server to use based on some criteria (typically load). You could have a load balance installed, but it wouldn't be serving any purpose. Another major reason for multiple servers isn't load balancing, but redundancy.
ribbon:
eureka:
enabled: false
Spring Cloud Netflix Zuul uses Netflix’s Ribbon to perform client-side load balancing, and by default, Ribbon would use Netflix Eureka for service discovery. You are skipping service discovery, so you've set ribbon.eureka.enabled
to false
. Since Ribbon now can’t use Eureka to look up services, you must specify an url for the meeting
service:
meeting:
ribbon:
listOfServers: localhost:8080
I will make it more clear for you.
The dependency org.springframework.cloud:spring-cloud-starter-netflix-zuul
, which you are currently using in the gatekeeper
project, has several compile dependencies:
com.netflix.zuul:zuul-core
org.springframework.boot:spring-boot-starter-web
org.springframework.boot:spring-boot-starter-actuator
org.springframework.cloud:spring-cloud-netflix-zuul
org.springframework.cloud:spring-cloud-starter
org.springframework.cloud:pring-cloud-starter-netflix-hystrix
org.springframework.cloud:spring-cloud-starter-netflix-ribbon
org.springframework.cloud:spring-cloud-starter-netflix-archaius
As you see, it constitutes many components gathered around the com.netflix.zuul:zuul-core
module (including Eureka for instance discovery and Ribbon for routing):
When you are launching the gatekeeper
application, the default ZuulProxyAutoConfiguration
configuration is being applied. It imports Ribbon configuration classes:
@Configuration
@Import({ RibbonCommandFactoryConfiguration.RestClientRibbonConfiguration.class,
RibbonCommandFactoryConfiguration.OkHttpRibbonConfiguration.class,
RibbonCommandFactoryConfiguration.HttpClientRibbonConfiguration.class,
HttpClientConfiguration.class })
@ConditionalOnBean(ZuulProxyMarkerConfiguration.Marker.class)
public class ZuulProxyAutoConfiguration extends ZuulServerAutoConfiguration { ... }
HttpClientRibbonConfiguration
, in turn, initialises RibbonLoadBalancingHttpClient
which is responsible for the error messages you saw.
That RibbonLoadBalancingHttpClient
by default utilises ZoneAwareLoadBalancer
which comes from a com.netflix.ribbon:ribbon-loadbalancer
package:
By default Zuul load balances using the
ZoneAwareLoadBalancer
from Ribbon. The algorithm is a round robin of the instances available in discovery, with availability zone success tracking for resiliency. The load balancer will keep stats for each zone and will drop a zone if the failure rates are above a configurable threshold.If you want to use your own custom load balancer you can set the
NFLoadBalancerClassName
property for that Ribbon client namespace or override thegetLoadBalancerClass()
method in theDefaultClientChannelManager
. Note that your class should extendDynamicServerListLoadBalancer
.
It explains that Zuul delegates routing and load balancing work to Ribbon components and proves that you are actually using Ribbon in the gatekeeper
project.
Unless you choose a different load balancer, you should go for my original answer.
I hope it will help.
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