Service discovery
Supporting different kinds of data flow topologies - request response, as well as streaming data; pub-sub, etc.
Provide common abstractions for efficient data serialization
Support backpressure and flow control, to rate limit requests
Support easy scaling of each component, including routing of messages or requests to multiple instances
Enable easy testing of multiple services (for example, see Akka’s sbt-multi-jvm plugin)
A common platform for application metrics
Distributed message or request tracing, to help with visibility and debugging
Support polyglot development - it should be possible to develop services in different languages
Hey guys,I would like to run an idea by the fine Akka community - which is to discuss what it would take to turn Akka into a platform for building a network of "microservices": each one independently redeployable and easy to change, yet through a common platform, take advantage of the distributed supervision, messaging and other goodies from Akka.Here are some characteristics of such a platform:
Service discovery Supporting different kinds of data flow topologies - request response, as well as streaming data; pub-sub, etc. Provide common abstractions for efficient data serialization Support backpressure and flow control, to rate limit requests Support easy scaling of each component, including routing of messages or requests to multiple instances Enable easy testing of multiple services (for example, see Akka’s sbt-multi-jvm plugin) A common platform for application metrics Distributed message or request tracing, to help with visibility and debugging Support polyglot development - it should be possible to develop services in different languagesI think many of these are already provided by Akka, but I wanted to run through each one in more detail:Service DiscoveryRight now every actor talks to another actor location-transparently; however, when looking up an external ActorRef, one does have to know the mechanism, ie is it looking up in cluster, or remote, etc.... is it another actorsystem etc... (this could have changed in 2.2 and 2.3, but I'm not up to date :-p) What I'm looking for is a mechanism-independent way of looking up actors, remote or not. IE, I should just need to do this:val downstreamActorRef = System.lookupByName(service = "tradingSystem", actor = "masterTrader", ....)Under the hood this looks up the actorRef using one of configurable mechanisms:- Akka Cluster is certainly one way to go, with nodes- At work we use Zookeeper and Curator. It would be great to make this platform support multiple discovery types
Data Flow Topology- Akka is pretty good at this already, supporting many types of data flow. The only concern I see is that you have to define the flow via the like of routers and such, which are defined in the code on each node, rather than externally via say a message queue (see ZMQ, NSQ etc). This can be mitigated through DI and configuration and things like that, of course.
Data SerializationIf we are using native Akka protocol to talk over the wire, this is already really good. One defines case classes, and Akka transparently serializes them over the network if the actor is remote. This is one thing about Akka that really appeals to me.So the question is can we make this work for Play / Akka HTTP transparently as well?Related - Polyglot supportHow would a Ruby/Python/etc process talk to an Akka network? My thoughts:- Easiest way would be to have a way to automagically generate HTTP endpoints that includes case class serialization to/from JSON. Type classes to handle special data types.- Did you guys define the Akka binary protocol and keep it stable? Client libraries could then be written for different langauges, but this doesn't solve the problem of message format -- Java serialization and Chill/Kryo won't work.
Backpressure and Flow ControlReactive streams looks really promising here. How it ties into routing, topologies, etc. I'd like to find out more about.Also, reactive streams won't work for request/response protocols.
Application Metrics and TracingMicroservices means it becomes more and more important to figure out what's going on across many services. Fortunately there's a lot of work in this area; multiple third party libs to provide automatic metrics; somebody wrote an Akka integration with Twitter's Dapper-like tracing system, and I have written a tracing/graphing system as well.
Hot ReloadsI didn't include this in the list above, because the assumption is that with lots of independent small services, they will be naturally easier to redeploy. Some will argue that the JVM is heavyweight (actually I think a lightly loaded JVM app is under 50MB, which is very reasonable), and will want Erlang-style hot reloads of individual actors. This is really tricky area though.
Anyways, I'd love to get the thoughts of the community about this idea of using Akka as a "microservice" platform.
It seems to me that service discovery could be well addressed by CRDTs, maybe an OR-Set or MC-Set. In the spare time that I never seem to have, I had thought about grabbing Patrik's CRDT lib and trying to implement service discovery on it to learn more about CRDTs. Fingers crossed, one of these days i'll get a chance to do it.
--
>>>>>>>>>> Read the docs: http://akka.io/docs/
>>>>>>>>>> Check the FAQ: http://doc.akka.io/docs/akka/current/additional/faq.html
>>>>>>>>>> Search the archives: https://groups.google.com/group/akka-user
---
You received this message because you are subscribed to the Google Groups "Akka User List" group.
To unsubscribe from this group and stop receiving emails from it, send an email to akka-user+...@googlegroups.com.
To post to this group, send email to akka...@googlegroups.com.
Visit this group at http://groups.google.com/group/akka-user.
For more options, visit https://groups.google.com/d/optout.
Patrik Nordwall
Typesafe - Reactive apps on the JVM
Twitter: @patriknw
It seems to me that service discovery could be well addressed by CRDTs, maybe an OR-Set or MC-Set. In the spare time that I never seem to have, I had thought about grabbing Patrik's CRDT lib and trying to implement service discovery on it to learn more about CRDTs. Fingers crossed, one of these days i'll get a chance to do it.
--
>>>>>>>>>> Read the docs: http://akka.io/docs/
>>>>>>>>>> Check the FAQ: http://doc.akka.io/docs/akka/current/additional/faq.html
>>>>>>>>>> Search the archives: https://groups.google.com/group/akka-user
---
You received this message because you are subscribed to the Google Groups "Akka User List" group.
To unsubscribe from this group and stop receiving emails from it, send an email to akka-user+...@googlegroups.com.
To post to this group, send email to akka...@googlegroups.com.
Visit this group at http://groups.google.com/group/akka-user.
For more options, visit https://groups.google.com/d/optout.
--
>>>>>>>>>> Read the docs: http://akka.io/docs/
>>>>>>>>>> Check the FAQ: http://doc.akka.io/docs/akka/current/additional/faq.html
>>>>>>>>>> Search the archives: https://groups.google.com/group/akka-user
---
You received this message because you are subscribed to a topic in the Google Groups "Akka User List" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/akka-user/QCYVY-dJlM8/unsubscribe.
To unsubscribe from this group and all its topics, send an email to akka-user+...@googlegroups.com.
Here are some characteristics of such a platform:
Service discovery
Supporting different kinds of data flow topologies - request response, as well as streaming data; pub-sub, etc.
Provide common abstractions for efficient data serialization
Support backpressure and flow control, to rate limit requests
Support easy scaling of each component, including routing of messages or requests to multiple instances
A common platform for application metrics
Distributed message or request tracing, to help with visibility and debugging
Support polyglot development - it should be possible to develop services in different languages
Here is an alternative approach for service discovery with out using Zookeeper and has better synergy with AKKA clustering; Consul[0].
Consul is based on the Raft protocol[1] for consensus. But Consul also makes uses of Serf’s[2] gossip protocol for LAN and WAN membership status and leader election.
Like etcd and others, Consul's features include service discovery and a similar key-value store, but also provides health checking functionality and the ability to span multiple data-centers out-of-the-box.
The multiple data-center support comes from Consul's use of its eventually consistent gossip protocol. I find this first class support for multiple datacenters to be an interesting leap ahead of other solutions that leave it up to the implementer to figure out.
Perhaps the integration can best be achieved with an akka extension that acts as a client to Consul potentially leveraging either the HTTP API [3] or the roc protocol [4].
With this I believe you could address the different consistency levels expressed (CP + AP) by all participants in this thread so far. In addition, it can scale to support the situations Brian has described. If nothing else I think it at least provides some good ideas for service discovery.
Regards,
Todd
[0] http://www.consul.io/
[1] https://ramcloud.stanford.edu/wiki/download/attachments/11370504/raft.pdf
[2] http://www.serfdom.io/
[3] http://www.consul.io/docs/agent/http.html
[4] http://www.consul.io/docs/agent/rpc.html
Data Flow Topology- Akka is pretty good at this already, supporting many types of data flow. The only concern I see is that you have to define the flow via the like of routers and such, which are defined in the code on each node, rather than externally via say a message queue (see ZMQ, NSQ etc). This can be mitigated through DI and configuration and things like that, of course.I’d propose to build only direct peer-to-peer communication into the fabric and model all other concerns (queues, pub-sub, etc.) as uniservices on top. These implementations will then naturally be part of the whole package, but I would rather not conflate different notions of message-passing under a common umbrella.
Data SerializationIf we are using native Akka protocol to talk over the wire, this is already really good. One defines case classes, and Akka transparently serializes them over the network if the actor is remote. This is one thing about Akka that really appeals to me.So the question is can we make this work for Play / Akka HTTP transparently as well?Related - Polyglot supportHow would a Ruby/Python/etc process talk to an Akka network? My thoughts:- Easiest way would be to have a way to automagically generate HTTP endpoints that includes case class serialization to/from JSON. Type classes to handle special data types.- Did you guys define the Akka binary protocol and keep it stable? Client libraries could then be written for different langauges, but this doesn't solve the problem of message format -- Java serialization and Chill/Kryo won't work.My current thoughts on this front (also for changing the Akka remote protocol to allow interoperability between different versions) go into the direction of CBOR as a kind-of binary JSON-like format that is friendly to streaming, compact, self-describing and standardized. In the end it will require a structural data format (i.e. not tied to JVM nominal types) to accomplish polyglot deployments. The reason to prefer it over protobuf is that it can be parsed without knowing the schema.The raw serialization implementation can be used for any number of use-cases, e.g. remoting, streams, persistence, etc.
Hot ReloadsI didn't include this in the list above, because the assumption is that with lots of independent small services, they will be naturally easier to redeploy. Some will argue that the JVM is heavyweight (actually I think a lightly loaded JVM app is under 50MB, which is very reasonable), and will want Erlang-style hot reloads of individual actors. This is really tricky area though.I fully agree, redeployment should be done on a per-JVM granularity, where one JVM possibly hosts multiple (related) uniservices.One thing that is commonly left out—even when citing Erlang—is resilience: it is of the utmost important to include a sane model for handling service failures, restarting or redeploying them, switching to backup topologies, etc. We have that within Akka and porting this to the way we express uniservice architectures is one of the most appealing aspects of this whole endeavor.
Hi
Let me add some notes based on my experience and further thoughts on this.
Am Montag, 2. Juni 2014 17:51:06 UTC+2 schrieb Evan Chan:Here are some characteristics of such a platform:
Service discovery
We've been using Zookeeper for discovering individual Akka based services on the network. ZK does this job very well. We tried Akka cluster when it was still experimental. Later we decided that a strong consistency model would be a better fit for the solution we needed to create. But it largely depends on your requirements. If you need to spin up thousands of JVMs then Akka cluster with its gossip protocol will scale very well. However, what we wanted to do is to create a low latency platform using a cell architecture[0], so you'd not have to deal with that many services. In our case a single ZK instance can handle a hundred services just fine.
One important aspect thats just as important as discovery is error handling. Having a single consistent view on your cluster certainly makes it easier to decide whenever a node needs to be removed. From my experience akka cluster using its gossip protocol can sometimes make it hard to find out exactly why nodes have been removed from the cluster (which is important to know for our customers). But thats just anecdotal evidence from my side. Maybe gossip based service discovery can also work fine, but I don't really see the benefits over zookeeper as long as you don't really need to run a very large cluster.
Supporting different kinds of data flow topologies - request response, as well as streaming data; pub-sub, etc.
Very interesting point. But how far would you go? Theres distributed platforms such as Storm [1] (not exactly a micro services platform, I know) that will provide features such as fault tolerance based its idea of how a flow topology should work. On the other hand you're loosing flexibility whenever you need to define a static topology of your services.
Pub-sub is really nice to work with as a developer. But its not suitable for every use-case and can make implementing data flows hard to follow. It would be great to have a platform that would support multiple models based on what you need. In this regard I always liked zeromq[2] for offering you a great deal of options for that, without getting in your way.
Provide common abstractions for efficient data serialization
Akka is pretty good at handling data serialization. Maybe each service description should also specify what kind of serialization protocol is used by the Akka endpoint. But I'd rather see this handled by Akka remoting instead of a microservices framework. E.g. it would be really nice being able to support multiple serialization protocols for your remote actors. Akka would need to figure out which one has been used by the sender and select the appropriate protocol on the receiver end (if supported).
Support backpressure and flow control, to rate limit requests
Lack of back pressure is by far the hardest problem i've came by when dealing with distributed akka applications. Especially for low latency, high throughput systems. Now I'm very happy to see reactive streams happening! Obviously I'm not the only person feeling the pain with this.
However, what does back pressure mean in context of microservices. If you need to call a service and none is available, how will you handle this on framework level? If there's data waiting to be processed but no service running for accepting this data, what does this mean for your data producers? When people talk about back pressure most of the time the discussion is reduced to mailbox congestion and producer/consumer interaction. But if you have a set of services all talking with each other without a well defined topology model, enabling back pressure in terms of transmission throttling for end to end communication isn't enough.
For example, say I have a billing service which would pull pending orders from a queue. Each order would be send to a payment service and afterwards to a mail confirmation service, which in turn also talks to a recommendation service to retrieve a list of items to suggest for further purchase to include in the order confirmation mail. Now in this case, what happens if the recommendation service is down? From a business perspective, its preferred to just keep sending confirmation mails without any recommendations and keep the billing process going. The developer should always be able to decide what to do in case of any end to end service interaction fails. Automatic back pressure could potentially be more dangerous than useful in those situations. In the microservices platform I'd love to use as a developer, I'd always be able to change the way how I interact with services based on the current cluster state and metrics. Services flows should be able to degenerate in case non-critical interactions won't be possible or certain services would just be slow.
Support easy scaling of each component, including routing of messages or requests to multiple instances
Creating solid routing algorithms in a push topology will be though. One possible option would be to take all remote mailbox sizes into account and calculate the average digestion rate. You'd need to consider which service is able to process the message in an acceptable time frame while routing a message to a remote service. Else some kind of backpressure would need to apply.
thanks for bringing this up! We have been discussing similar things at Akka HQ, so far without the ability to dedicate resources to such an effort. I agree with Thomas that Actors already cover the basics, I would call the Actor Model the ideal substrate on which we can efficiently and conveniently grow uniservices(*).[specific replies inline](*) I prefer this term because it focuses on the Single Responsibility Principle (see also the introduction of modules) instead of the rather irrelevant notion of “size” .
One thing that is commonly left out—even when citing Erlang—is resilience: it is of the utmost important to include a sane model for handling service failures, restarting or redeploying them, switching to backup topologies, etc. We have that within Akka and porting this to the way we express uniservice architectures is one of the most appealing aspects of this whole endeavor.
And there is another aspect. Especially for larger projects microservices are great to "enforce" a share nothing philosophy. Using akka serialization, I either have to share the messages or use protobuf + code generation, which is again more complicated. I am not sure whether that can be achieved with CBOR standard you mentioned, but using JSON via HTTP has the advantage that I don't have to share code while it's still very easy to use.
On Wednesday, June 11, 2014 2:35:27 AM UTC-7, Carsten Saathoff wrote:And there is another aspect. Especially for larger projects microservices are great to "enforce" a share nothing philosophy. Using akka serialization, I either have to share the messages or use protobuf + code generation, which is again more complicated. I am not sure whether that can be achieved with CBOR standard you mentioned, but using JSON via HTTP has the advantage that I don't have to share code while it's still very easy to use.I think the "JSON means you don't have to share code" is a bit false. Everywhere that uses the JSON interface, especially if it is a compiled language like Java or Scala, is going to need quite a bit of scaffolding, most likely a client, and serialization/deserialization code to work with that REST API. If you really stick by the "shared nothing", this significant chunk of code must be duplicated, leading to errors and a maintenance nightmare. It is true that with Akka case classes you _must_ share the code, but I would say in practice this is far easier than having to set up clients and deser code at every client service.
Hi Roland,Thanks for thoughts...
On Thursday, June 5, 2014 6:57:38 AM UTC-7, rkuhn wrote:Data Flow Topology- Akka is pretty good at this already, supporting many types of data flow. The only concern I see is that you have to define the flow via the like of routers and such, which are defined in the code on each node, rather than externally via say a message queue (see ZMQ, NSQ etc). This can be mitigated through DI and configuration and things like that, of course.I’d propose to build only direct peer-to-peer communication into the fabric and model all other concerns (queues, pub-sub, etc.) as uniservices on top. These implementations will then naturally be part of the whole package, but I would rather not conflate different notions of message-passing under a common umbrella.Sounds good. And Akka already has support for ZMQ...
Data SerializationIf we are using native Akka protocol to talk over the wire, this is already really good. One defines case classes, and Akka transparently serializes them over the network if the actor is remote. This is one thing about Akka that really appeals to me.So the question is can we make this work for Play / Akka HTTP transparently as well?Related - Polyglot supportHow would a Ruby/Python/etc process talk to an Akka network? My thoughts:- Easiest way would be to have a way to automagically generate HTTP endpoints that includes case class serialization to/from JSON. Type classes to handle special data types.- Did you guys define the Akka binary protocol and keep it stable? Client libraries could then be written for different langauges, but this doesn't solve the problem of message format -- Java serialization and Chill/Kryo won't work.My current thoughts on this front (also for changing the Akka remote protocol to allow interoperability between different versions) go into the direction of CBOR as a kind-of binary JSON-like format that is friendly to streaming, compact, self-describing and standardized. In the end it will require a structural data format (i.e. not tied to JVM nominal types) to accomplish polyglot deployments. The reason to prefer it over protobuf is that it can be parsed without knowing the schema.The raw serialization implementation can be used for any number of use-cases, e.g. remoting, streams, persistence, etc.This shouldn't be hard - after all serialization is already pluggable. Is there momentum behind CBOR though?
Hot ReloadsI didn't include this in the list above, because the assumption is that with lots of independent small services, they will be naturally easier to redeploy. Some will argue that the JVM is heavyweight (actually I think a lightly loaded JVM app is under 50MB, which is very reasonable), and will want Erlang-style hot reloads of individual actors. This is really tricky area though.I fully agree, redeployment should be done on a per-JVM granularity, where one JVM possibly hosts multiple (related) uniservices.One thing that is commonly left out—even when citing Erlang—is resilience: it is of the utmost important to include a sane model for handling service failures, restarting or redeploying them, switching to backup topologies, etc. We have that within Akka and porting this to the way we express uniservice architectures is one of the most appealing aspects of this whole endeavor.You mean Actor become() and friends?Failure handling is inherently tied to the topology ... I'm not sure what common themes we can bring to the table, other than distributed supervision should be a fundamental piece (and a strength of Akka's).
Anyways, I'd love to get the thoughts of the community about this idea of using Akka as a "microservice" platform.Much appreciated that you started this, and sorry for taking so long to respond, the last few days were a bit hectic on my end.Regards,
Dr. Roland Kuhn
Akka Tech Lead
Typesafe – Reactive apps on the JVM.
twitter: @rolandkuhn
--
>>>>>>>>>> Read the docs: http://akka.io/docs/
>>>>>>>>>> Check the FAQ: http://doc.akka.io/docs/akka/current/additional/faq.html
>>>>>>>>>> Search the archives: https://groups.google.com/group/akka-user
---
You received this message because you are subscribed to the Google Groups "Akka User List" group.
To unsubscribe from this group and stop receiving emails from it, send an email to akka-user+...@googlegroups.com.
To post to this group, send email to akka...@googlegroups.com.
Visit this group at http://groups.google.com/group/akka-user.
For more options, visit https://groups.google.com/d/optout.
bestCarsten
--
>>>>>>>>>> Read the docs: http://akka.io/docs/
>>>>>>>>>> Check the FAQ: http://doc.akka.io/docs/akka/current/additional/faq.html
>>>>>>>>>> Search the archives: https://groups.google.com/group/akka-user
---
You received this message because you are subscribed to the Google Groups "Akka User List" group.
To unsubscribe from this group and stop receiving emails from it, send an email to akka-user+...@googlegroups.com.
To post to this group, send email to akka...@googlegroups.com.
Visit this group at http://groups.google.com/group/akka-user.
For more options, visit https://groups.google.com/d/optout.
13 jun 2014 kl. 08:27 skrev Carsten Saathoff <car...@kodemaniak.de>:
Am Freitag, 13. Juni 2014 07:39:15 UTC+2 schrieb Evan Chan:On Wednesday, June 11, 2014 2:35:27 AM UTC-7, Carsten Saathoff wrote:And there is another aspect. Especially for larger projects microservices are great to "enforce" a share nothing philosophy. Using akka serialization, I either have to share the messages or use protobuf + code generation, which is again more complicated. I am not sure whether that can be achieved with CBOR standard you mentioned, but using JSON via HTTP has the advantage that I don't have to share code while it's still very easy to use.I think the "JSON means you don't have to share code" is a bit false. Everywhere that uses the JSON interface, especially if it is a compiled language like Java or Scala, is going to need quite a bit of scaffolding, most likely a client, and serialization/deserialization code to work with that REST API. If you really stick by the "shared nothing", this significant chunk of code must be duplicated, leading to errors and a maintenance nightmare. It is true that with Akka case classes you _must_ share the code, but I would say in practice this is far easier than having to set up clients and deser code at every client service.I think what you share is the API. Depending on how complicated the API is, it might be absolutely feasible to duplicate the API layer but gain decoupling. With all the good JSON and HTTP libs, writing such a layer is rather easy. I think decoupling of (micro)services is extremely important, and using the same set of case classes means you have an code-level dependency. Using case classes everywhere also means that integrating a service written in another language will be more complicated. But having the freedom to try out new stuff is another big advantage of microservices.So, don't get me wrong, I am not proposing everything should exclusively communicate via HTTP and JSON, but when we are talking about a microservice platform, I think decoupling of services also on the code level is an extremely important aspect. And I am also aware that HTTP+JSON are not very efficient, so that a more compact alternative such as CBOR sounds like a good idea. And ultimatively, this should probably be configurable, such that in projects where sharing of messages and API code is required, this can be done as well.This goes in the same direction I am currently exploring: instead of agreeing on the case classes (which means agreeing on fully-qualified class names) we could switch to a more structural approach, meaning that the message itself consists of data that can be parsed without knowing the schema. The recipient can then decide how to respond by querying that structure and extracting what it needs or understands. The gain is that interoperability between different platforms or segregated parts or a larger application or different versions of the same services becomes a lot easier than today. Of course the right content needs to arrive at the right place, but all incidental baggage (like the color of the parcel wrapping—the FQCN) is removed.RESTful APIs clearly are the inspiration for this line of thinking; are there any fundamental downsides to this approach?
Hey guys,I would like to run an idea by the fine Akka community - which is to discuss what it would take to turn Akka into a platform for building a network of "microservices": each one independently redeployable and easy to change, yet through a common platform, take advantage of the distributed supervision, messaging and other goodies from Akka.
Related - Polyglot supportHow would a Ruby/Python/etc process talk to an Akka network? My thoughts:- Easiest way would be to have a way to automagically generate HTTP endpoints that includes case class serialization to/from JSON. Type classes to handle special data types.- Did you guys define the Akka binary protocol and keep it stable? Client libraries could then be written for different langauges, but this doesn't solve the problem of message format -- Java serialization and Chill/Kryo won't work.
--
>>>>>>>>>> Read the docs: http://akka.io/docs/
>>>>>>>>>> Check the FAQ: http://doc.akka.io/docs/akka/current/additional/faq.html
>>>>>>>>>> Search the archives: https://groups.google.com/group/akka-user
---
You received this message because you are subscribed to a topic in the Google Groups "Akka User List" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/akka-user/QCYVY-dJlM8/unsubscribe.
To unsubscribe from this group and all its topics, send an email to akka-user+...@googlegroups.com.
To post to this group, send email to akka...@googlegroups.com.
Visit this group at http://groups.google.com/group/akka-user.
For more options, visit https://groups.google.com/d/optout.
I see that the service discovery may closely resemble with the same approach used by DOSGI.
http://cxf.apache.org/dosgi-architecture.html
An approach seems to me easier adaptation to AKKA.
Regards,
Adriano Santos
You received this message because you are subscribed to the Google Groups "Akka User List" group.
To unsubscribe from this group and stop receiving emails from it, send an email to akka-user+...@googlegroups.com.