-
Notifications
You must be signed in to change notification settings - Fork 160
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Consul based service discovery #202
Consul based service discovery #202
Conversation
# Set the following in your application.conf if you want to use this discovery mechanism: | ||
# impl = akka-consul | ||
|
||
# configured the akka-consul provider |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
configured => configure
…ce for embedded consul test
…ce for embedded consul test
Does anyone have any idea how to fix:
in travis CI? |
That seems like some sort of infra problem - I restarted the build. |
Thanks a lot, I'll review in depth on monday :-) |
Well, 5 days late but reviewing now; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lookin good! Some comments in line and two general ones I'd like to ask:
- we need some docs about this, could you add a note how one would use this in the discovery.md file under it's own section? We likely will refactor the docs a bit in the future but a small note in there would be good already :-)
- Since this assumes that apps register in consul, it also means that we need the "register myself in consul" side right? This is I think the first instance of such integration we have here in akka-management so let's make sure we set a good example. It seems to me that such application on startup should write it's keys to consul- so others will find it. Could we / should we add such
register()
method to the discovery class there and show how to use it? I think it's pretty powerful if we then make it a general style, so regardless if one uses zk or consul or something else the style would be the same (but that's for later).
@@ -1,6 +1,6 @@ | |||
enablePlugins(JavaAppPackaging) | |||
|
|||
packageName in Universal := "app" // should produce app.zip | |||
com.typesafe.sbt.SbtNativePackager.autoImport.packageName in Universal := "app" // should produce app.zip |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
was this needed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My sbt was complaining about, but it's probably a local issue.
@@ -0,0 +1,20 @@ | |||
###################################################### | |||
# Akka Service Discovery Consul Config # | |||
###################################################### |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nitpick about the # position ;-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
consul-host = "127.0.0.1" | ||
consul-port = 8500 | ||
|
||
application-name-tag-prefix = "system:" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you add a small comment above each of the keys what it's about?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So here we would have to explain that we expect values to be present under "system:name-of-my-actor-system" right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added
Consul.builder().withHostAndPort(HostAndPort.fromParts(settings.consulHost, settings.consulPort)).build() | ||
|
||
override def lookup(name: String, resolveTimeout: FiniteDuration): Future[SimpleServiceDiscovery.Resolved] = { | ||
import system.dispatcher |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we try to use implicit val ec = system.dispatchet
everywhere for safety -- the import if executed in a future technically could reach a null (rarely, and only during system shutdown etc etc, but we try to use the val anyway)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
|
||
private lazy val settings = ConsulSettings.get(system) | ||
private lazy val consul = | ||
Consul.builder().withHostAndPort(HostAndPort.fromParts(settings.consulHost, settings.consulPort)).build() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do they have to be lazy?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nope,
override def beforeAll(): Unit = { | ||
super.beforeAll() | ||
consul = ConsulStarterBuilder.consulStarter().withHttpPort(8500).build().start() | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please move the beforeAll above the tests (right next to the var)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it works without var
|
||
override def beforeAll(): Unit = { | ||
super.beforeAll() | ||
consul = ConsulStarterBuilder.consulStarter().withHttpPort(8500).build().start() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
seems there's no reason to keep it a var, can we make it a val and innit in constructor?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
project/Dependencies.scala
Outdated
Seq( | ||
"com.orbitz.consul" % "consul-client" % "1.1.2", | ||
"com.pszymczyk.consul" % "embedded-consul" % "1.0.2" % "test" | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add a comment with the license next to each of those lines, we have to make sure they are apache compatible (i.e. no GPL code)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added
ResolvedTarget(catalogService.getServiceAddress, Some(port.getOrElse(catalogService.getServicePort))) | ||
} | ||
|
||
private val getServicesWithTags = ((callback: ConsulResponseCallback[util.Map[String, util.List[String]]]) => |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could this be a normal method instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
implicit class ConsulResponseFutureDecorator[T](f: ConsulResponseCallback[T] => Unit) { | ||
def asFuture: Future[ConsulResponse[T]] = { | ||
val callback = new ConsulResponseFutureCallback[T] | ||
f(callback) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could f
throw? Let's make sure that then the Future is failed rather than the asFuture throwing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I did what you asked for, but please take another look
…omments addressed
About the registration method - I assume that most of the people doing this already have something in place like I based the decisions on implementation on an actual production running service and it worked in my case (I mean, I deployed it on prod already ;) to check if it actually work) but in other cases it might not be accurate, but the generic approach with tags should work most of the times. I will add the discovery.md as soon as I find some spare time and write it all down. |
Note that this project replaces ConstructR, which is already in archived mode even: hseeberger/constructr#174 So, no, we can not say that people will have ConstructR or anything similar to it. We also assume deployments which are no-extra-tooling -- plain jars that someone has run somewhere so there should be standard way to register in such registries, even if many people will not use them because some other mechanism performs the registration for them. |
I meant that most of the setup for existing application is already done somewhere and since ConstructR does not register the service in Consul there has to be another mechanism in place already. Adding a registration method in my opinion is not easy (you have to create health checks and know what is exposed where in application - you probably have all the information anyway but still a generic solution would be hard to implement) and will be omitted most of the time. Said that, I agree that this would be a powerful tool and would allow for quick set up of the cluster with low effort and very quickly. While implementing registration in Consul a lot of configuration options would be have to be added, but it's doable. |
That's a good summary – I think it's valuable, but we'll see when/if we end up providing it or not. As for this PR, I would like to merge it but it needs a bit of documentation -- would you be able to add it? Thanks a lot |
Sorry, I was quite busy with some other stuff. I suck at writing documentation so please check it and if it does not make sense I'll try to write it in some other way. |
discovery-consul/discovery.md
Outdated
@@ -0,0 +1,36 @@ | |||
How to set up Consul based discovery for Akka Cluster |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Docs in general are under the docs project :-)
https://github.com/akka/akka-management/blob/master/docs/src/main/paradox/discovery.md
Here no one would see the documentation after all :-)
Would you want to give adjusting it a try and putting in that spot?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops, I knew something was not right ... will add it there
Thanks! It's a good start :) I'll merge and we'll see what feedback we get. I'll also want to mark it somehow as community contriubted / "not supported" or something similar until we're confident in it... hope that's fine. Exact wording for these things we'll figure out during this week (we got a team meeting about it :)) |
Fixes #198