Spring Cloud Zookeeper - override default registration process - spring

The documentations states that
The default service name, instance id and port, taken from the Environment, are ${spring.application.name}, the Spring Context ID and ${server.port} respectively.
Is there a hook which can be used to override this behavior -
registering a different server and port value?
e.g. there is the EurekaClientConfigBean which be used with Spring Cloud Eureka to achieve the same result.

Related

Delay EurekaClient startup in Spring Boot application

Docs says that Eureka client can be integrated into Spring Application very simply, just add one annotation to your configuration class and several properties into your application.properties. But says nothing about manual startup/shutdown of client. I want to customize behaviour of that client (or delay its init, because (wow!) entire logic lays in client's constructor): instead of background registration via Spring Boot's auto-configuration, client must register in Eureka server when application (with Eureka client) itself gets initialized, and only after that application will be able to gather metadata, put it to Eureka client's metadataMap and then start registration process in Eureka server. Of course, I can take ApplicationInfoManager instance and call registerAppMetadata, but what do if dependant application (also registered in the server) requires that applications must register with required metadata?
you could configure a health page and point the health check to it - https://cloud.spring.io/spring-cloud-netflix/multi/multi__service_discovery_eureka_clients.html#_status_page_and_health_indicator

Spring Boot Actuator + Spring Boot Admin - Is there a way to define a custom management url?

Is there a way I can define the port for the management URLs (not the management.server.port) so that spring boot admin can identify the actuator URLs from the spring boot app for monitoring?
I'm running the spring boot app in a docker container and it's externally exposed on a different port using the Kubernetes NodePort.
If you are using service discovery for application lookup you could define the exposed management port in instance metadata. This metadata is used to build up the management URL.
More details documented here:
http://codecentric.github.io/spring-boot-admin/current/#spring-cloud-discovery-support
Handling is done in de.codecentric.boot.admin.server.cloud.discovery.DefaultServiceInstanceConverter
Example for Eureka:
eureka.instance.metadata-map.management.port=[K8S-EXPOSED-PORT]
If you are using Service Discovery, take a look into DefaultServiceInstanceConverter, try specifying the management.port property.
If you are not using Service Discovery, then take a look into de.codecentric.boot.admin.server.domain.values.Registration, you might need to use the builder apis to register your application correctly (try to set managementUrl properly). Note, you will need to do this in your client application (the one which is being monitored).

Configure FeignClient to use url by env variable without disabling Eureka

My current environment is a Spring Cloud setup using Eureka and I have multiple Feign clients in the application. What I want to do is to allow most of my Feign clients to resolve their services via the discovery server but prevent one or two from doing so in order to use my local instance that I am currently developing on. I'm running the service I'm developing and the client application locally.
I would like the client application to use discovery for all over service discovery and override one Feign Client to use only my local running service.
Is there a way to do this without disabling Eureka on the client? I have explored these two questions (one, two) and have not managed to get the listOfServers field to have any impact unless I disabled Eureka. If it matters in working on this I made the service I wish to connect to not register with eureka.
You can specify a URL for a specific FeignClient without disabling Eureka client with property <ribbonclientname>.ribbon.NIWSServerListClassName property.
Assume that service id for directing routing is testA. You can define the below property without disabling Eureka client.
testA:
ribbon:
NIWSServerListClassName: com.netflix.loadbalancer.ConfigurationBasedServerList
listOfServers: ${url for your test server}
If you specify com.netflix.loadbalancerConfigurationBasedServerList as NIWSServerListClassName, ribbon client inside your Feign client will use address that was given via listOfServers property without disabling eureka.
I got a way to pass the environment variables in a very simple way:
interface FeignClient
#FeignClient(url = "https://"+"\${url}", name = "limit", decode404 = true)
interface HbFeignClient {
#GetMapping("/credit-limit")
fun getLimitCompany(#RequestParam(required = true) companyId: Long): ResponseEntity<Any>
properties
#URL
url=${URL}
.env
URL=https:localhost:8080

Spring cloud registering multiple instances of same service

I am developing a microservice, using Spring Boot, that exposes REST Endpoint. Because of scalability, I have to run multiple instances of this services on a different port. What will be the configurations for the applications so that it can register with eureka and requests are load balanced? I am using Spring cloud config, Eureka server and zuul.
Attaching following entries in the client properties file will do the trick. This is for Spring cloud config dalston
eureka.instance.instanceId=${spring.application.name}:${spri‌​ng.application.insta‌​nce_id:${random.valu‌​e}}
I guess you meant to register with Eureka instead of Config server.
To register multiple instances that might be running in the same host but listening on a different port you would need to set eureka.instance.metadataMap.instanceId to a unique value maybe using:
eureka.instance.metadataMap.instanceId=${spring.application.name}:${random.int}

Does Eureka and Ribbon work for non spring boot application?

I am rewriting a Spring MVC system.
The system is something like this in simple:
[Gateway<->Backend Services<->Databases], where Gateway is a controller simply for authentication and forwarding the requests to Backend services.
The Backend services will be refactored to micro-services. I will use Eureka service to do registration for each of them. So eventually the architecture will be: [Gateway <-> Eureka <-> Backend micro-services <-> Databases]. The Gateway will lookup the registries from Eureka server and call the micro services.
However, the Gateway is not a spring boot application(and will NOT be rewritten as Spring boot), thus I don't believe Spring's eureka features (#EnableEurekaClient , DiscoveryClient, ect.) can be adopted easily as the examples do. Actually I tried adding the eureka client annotation to Gateway's controller, which caused my application collapsed.
Moreover, Ribbon is needed in the Gateway for client side loading balancing. But the same concern is as above.
//Update on 1st Nov.
I have set up an Eureka server and a client, both of which are written in spring boot. I am using these two application for my Spring MVC testing. The server and client are running well.
Server's configuration application.properties is as below
server.port=8761
spring.application.name=service-itself
eureka.client.service-url.default-zone=http://localhost:8761/eureka/
eureka.client.register-with-eureka=true
eureka.client.fetch-registry=false
logging.level.com.netflix.eureka=OFF
logging.level.com.netflix.discovery=OFF
client's is as below: application.yml
spring:
application:
name: say-hello
server:
port: 8090
eureka:
client:
service-url:
defaultZone: http://${eureka.host:localhost}:${eureka.port:8761}/eureka/
When accessing the Eureka dashboard localhost:8761, I can see that client has been registered.
For my Spring MVC gateway, as it is not a Spring boot project, so I copied the example to my project simply for testing whether it can connect to the Eureka server and retrieve the registered the instance of "say-hello" client. Unfortunately, it cannot do so with saying "Cannot get an instance of example service to talk to from eureka" which is printed at line 76 in the example class.
Here is the eureka-client.properties placed in gateway's classpath. I can confirmed that the Client class is reading the config file.
eureka.name=gatewayEurekaClient
eureka.vipAddress=say-hello
eureka.port=8761
eureka.preferSameZone=true
eureka.preferSameZone=true
eureka.shouldUseDns=false
eureka.serviceUrl.default=http://localhost:8761/eureka
eureka.serviceUrl.defaultZone=http://localhost:8761/eureka
Moreover, this is the debug information when new DiscoveryClient(applicationInfoManager, clientConfig); is being executed
instanceInfo InstanceInfo (id=234)
actionType null
appGroupName "UNKNOWN" (id=246)
appName "GATEWAYEUREKACLIENT" (id=247)
asgName null
countryId 1
dataCenterInfo PropertiesInstanceConfig$1 (id=248)
healthCheckExplicitUrl null
healthCheckRelativeUrl "/healthcheck" (id=253)
healthCheckSecureExplicitUrl null
healthCheckUrl "http://A156N7AB89AXNZQ:8761/healthcheck" (id=254)
homePageUrl "http://A156N7AB89AXNZQ:8761/" (id=255)
hostName "A156N7AB89AXNZQ" (id=256)
instanceId "A156N7AB89AXNZQ" (id=256)
ipAddr "10.209.66.64" (id=257)
isCoordinatingDiscoveryServer Boolean (id=258)
isInstanceInfoDirty false
isSecurePortEnabled false
isUnsecurePortEnabled true
lastDirtyTimestamp Long (id=260)
lastUpdatedTimestamp Long (id=263)
leaseInfo LeaseInfo (id=264)
metadata ConcurrentHashMap<K,V> (id=266)
overriddenstatus InstanceInfo$InstanceStatus (id=267)
port 8761
secureHealthCheckUrl null
securePort 443
secureVipAddress null
secureVipAddressUnresolved null
sid "na" (id=270)
status InstanceInfo$InstanceStatus (id=271)
statusPageExplicitUrl null
statusPageRelativeUrl "/Status" (id=272)
statusPageUrl "http://A156N7AB89AXNZQ:8761/Status" (id=273)
version "unknown" (id=274)
vipAddress "say-hello" (id=275)
vipAddressUnresolved "say-hello" (id=275)
I am running out of idea. Can anyone please give a hand on this problem?
Ribbon (https://github.com/Netflix/ribbon) and Eureka (https://github.com/Netflix/eureka) can work without Spring (and that is the way they were developed in the first place) but you will need to put a bit more effort into configuring everything to your needs.
Support for Ribbon and Eureka in Spring is part of the Spring Cloud project (and mvn group id), not Spring Boot. I don't think boot is mandatory. Ribbon and Eureka themselves are provided by Netflix.
For ribbon, you need to define your own #LoadBalanced RestTemplate #Bean anyway. #EnableDiscoveryClient should work as long as the dependencies have spring cloud eureka and your class is a #Configuration class.
Short answer is - why not try a quick test? :).

Resources