加载中

I‘ve been using microservice architectures before I knew they were called so. I used to create pipeline applications made up of isolated modules which interacted with each other through queues. Since then, a number of (ex)ThoughtWorks gurus have talked about microservices. Fred George[1], then James Lewis[2] and finally Martin Fowler[3] have all blogged about microservices, all of them helping to make it the next buzzword ­ and now every company wants to have few microservices.

Nowadays there are #hashtags, endorsements, likes, trainings, even two day conferences [4] about it. The more I read and listen about microservice architectures, the more I realize how Apache Camel (and the accompanying projects around it) fits perfectly with this style of applications. In this post we will see how the Apache Camel framework can help us create microservice style applications in Java with few lines of code.

在我还不知道什么叫微服务架构的时候我就使用过它。以前,我写了一些管道程序(pipeline application),它由一些相互和队列交互的模块构成。自那之后,一批ThoughtWorks的专家也讨论过微服务。Fred George[1],接着是James Lewis[2]还有 Martin Fowler[3] 都写博文讨论微服务,使得微服务变成了下一个时髦术语,现在每个公司都想使用一些微服务。

现在有一些关于它的标签:endorsements,likes,trainings,甚至two day conferences.关于它的事情听得越多,意识到Apach Camel越来越搭配这种风格的程序。在这篇博文中,我们可以看到Apach Camel框架可以帮助我们用几行Java代码创建微服务风格的应用程序。

Microservices Practices

There is nothing new in microservices. Many similar applications have been designed and implemented as such for a long time. Microservices is just a new term that describes a style of software systems that have certain characteristics and follow certain principles. It is an architectural style where an application or software system is composed of individual standalone services communicating using lightweight protocols in event based manner. In the same way as TDD helps us to create decoupled single responsibility classes, microservices principles guide us to create simple applications at system level.

Here, we will not discuss the principles and characteristics of such architectures or argue whether it is a way of implementing SOA or a totally new approach to application design, but rather look at the most common practices used for implementing microservices and how Apache Camel can helps us accomplish that in practice. There is not a definitive list (yet) but if you read around or watch the videos posted above, you will notice that the following are quite common practices for creating microservices:

微服务实践

在微服务架构中没有什么新东西。很久以前就有人设计并实现了很多类似的应用。微服务只是一个新名词,它描述了一种拥有某些特点并遵从某些原则的软件体系风格。它是这样一种架构风格:一个应用或软件由多个各自独立的服务组成,服务之间以一种基于事件的轻量级协议来进行通信。在同样的方式下,TDD帮助我们创建了单一职责的类,微服务原则可以在系统级别上指导我们创建出简单的应用。

本文中,我们将不会讨论微服务的原则或者特性,也不会讨论它到底是实现SOA的一种方式还是一种全新的软件设计过程,我们只是来看一下微服务的常见的实践方式,以及Apache Camel是如何帮助我们实现微服务的。现在关于微服务还没有一个权威的定义,但是如果你看过上面提到的文章或视频,你会发现,下面这些都是微服务的很常见的实践方式:

1. Small in size. The very fundamental principle of microservices says that each application is small in size and it only does one thing and does it well. It is debatable what constitutes small or large, the number varies from 10 LOC to 1000 but personally, I like the idea that it should be small enough to fit in your head. There are people with big heads, so even that is debatable ;) but I think that as long as an application does one thing and does it well so that it is not considered a nanoservice[5], that is a good size.

Camel applications are inherently small in size. A CamelContext with couple of routes with error handling and helper beans is approximately 100 LOC. Thanks to Camel DSLs and URIs for abstracting endpoints, receiving an event either through HTTP or JMS, unmarshaling it, persisting and sending a response back is around 50 LOC. That is small enough to be understood end­to­end easily, rewritten and even thrown away without feeling any remorse.

1. 小规模. 微服务的最基本的原则指的是,每个应用程序规模很小,只专注于处理一件事,并做得非常好。从10 LOC到1000,组成程序规模的大小一直是一个有争议的话题。我个人倾向这样一个观点,程序的规模应该刚好容纳下你的脑袋。很多人的脑袋很大的,所以这还是一个有争议的话题(译者注:此处是黑色幽默,可忽略)。我认为,一旦一个程序只做一件事并做得很好,这只是一个很好的规模,不是一个纳米服务(nanoservice)。The very fundamental principle of microservices says that each application is small in size and it only does one thing and does it well. 

Camel程序与生俱来就是规模就小.一个同时具有错误处理和helper beans的CamleContext大约有100LOC(line of code).由于有了Camel DSLs和URIs来提取终端地址,通过HTTP或者JMS接受事件,解包并发送响应反馈也不过50行代码(LOC).这对于理解端对端来说足够规模小了,重写或丢弃这样的小规模代码也没有什么遗憾。

2. Having transaction boundaries. An application consisting of multiple microservices forms an eventually consistent system of systems where the state of the whole system is not known at any given time. This on its own creates a barrier for understanding and adopting microservices in teams who are not used to work with this kind of distributed applications. Even though the state of the whole system is not fixed, it is important to have transaction boundaries that define where a message currently belongs.

Ensuring transactional behaviour across heterogeneous systems is not an easy task, but Camel has great transactional capabilities. Camel has endpoints that can participate in transactions, transacted routes and error handlers, idempotent consumers and compensating actions, all of which help developers easily create services with transactional behavior.

2. 具有事务边界。 一个由多个微服务构成的应用就形成了一个最终一致性的系统,而多个这种系统组成的大系统,其整体状态在给定时间点上都是不可知的。这就等于自己给自己设置了一个障碍,使得那些不熟悉分布式应用的团队更难于理解进而采用微服务架构。即使整个系统的状态不固定,使用事务边界来定义消息的归属也是很重要的。

在异构系统中确保事务化的操作可不是那么容易,但是Camel却具有很强的事务支持能力。Camel拥有可以参与事务的终端、事务化的路由和错误处理、幂等的消费者和补偿操作,所有这些能帮助开发者轻松的创建出具有事务化行为的服务。

3. Self monitoring. This is one of my favorite areas of microservices. Services should expose information that describes the state of various resources it depends on and the service itself. These are statistics such as average, min, max time to process a message, number of successful and failed messages, being able to track a message, memory usage and so forth.

This is something you get OOTB with Camel without any effort. Each Camel application gathers JMX

statistics by default for the whole application, individual routes, endpoints and custom beans. It will tell you how many messages have completed successfully, how many failed, where they failed, etc. This is not read only API, JMX allows also updating and tuning the application at run time, so based on these statistics, using the same API you can tune the application accordingly. Also the information can be accessed with tools such as jConsole, VisualVM, Hyperic HQ, exposed over HTTP using Jolokia or feed into a great web UI called Hawtio[6].

Figure 1: Hawtio

3. 自我监测。 这是我最喜欢的微服务的特性之一。服务应该提供信息来描述它所依赖的各种资源的状态和它自己的状态。这都是些统计信息,比如处理一个消息的平均时间、最大最小时间,成功和失败的消息的个数,可以跟踪一个消息,内存使用率等等。

这是Camel的开箱即用的功能。每一个Camel应用都会默认搜集JMX统计信息,包括整个应用的信息、私有路由的信息、终端和消费组件的信息等。它会告诉你有多少消息成功处理了,有到少失败了,在哪儿失败的,等等。这些API不是只读性的,JMX也允许在运行期间对程序进行更新和调整,也就是说你可以使用同一套API,根据这些统计信息来相应的调整应用程序。这些统计信息也可以用其它工具来访问,比如jConsole,VisualVM,Hyperic HQ等,也可以用Jolokia通过HTTP进行访问,或者把信息提供给一个叫做Hawtio[6]的很棒的web UI组件。

图 1: Hawtio

If the functionality that is available with OOTB doesn't fit your custom requirements, there are multiple extension points such as the nagios, jmx, amazon cloudwatch components and Interceptors for custom events.

Logging in messaging applications is another challenge, but Camel's MDC logging combined with Throughput logger makes it easy to track individual messages or get aggregated statistics as part of the logging output.

5. Designed for failure. Each of the microservices can be down or unresponsive for some time but that should not bring the whole system down. Thus microservices should be fault tolerant and be able to recover when that is possible.

Camel has lots of helpful tools and patterns to cope with these scenarios too. Dead Letter Channel can make sure messages are not lost in case of failure ­ the retry policy can send a message a couple of times for certain error conditions using custom backoff method and collision avoidance. Patterns such as Load balancer which supports Circuit breaker[7], Failover and other policies, Throttler to make sure certain endpoints do not get overloaded, Detour, Sampler, are all needed in various failure scenarios. So why not use them rather than reinventing the wheel in each service?

如果开箱即用的功能不能满足你的个性化需求,也有一些扩展方式可以选择,比如nagios, jmx, amazon云监控组件和自定义事件拦截器等。

消息型应用的日志是另一个挑战,但是Camel的MDC日志结合Throughput日志器,就可以很容易的来跟踪某些信息或者获取日志信息聚合后的统计信息。

5. 为处理失败而设计。 单个微服务有可能宕机或者一段时间内无响应,但这不应该导致整个系统不可用。所以微服务应该能够容灾并在可能的时候进行恢复。

Camel也有许多有用的工具和模式来处理这些情形。Dead Letter Channel可以确保消息在传输失败的时候不会丢失,在某些错误产生时,重试策略可以借助于自定义后备方法和冲突避免策略,把一个消息进行多次发送。模式方面,比如支持断路器[7]的Load balancer(负载均衡器), 比如Failover(容灾)和其它策略,比如Throttler(节流阀)可以确保某个节点不会负载过重,还有Detour, Sampler也都是在各种出错情形下需要用到的。所以,有什么理由不用这些,而要在每个服务里重新造轮子呢?

6. Highly Configurable. It should be easy to configure the same application for high availability, scale it for reliability or throughput, or said another way: have different degrees of freedom through configuration. When creating a Camel application using the DSLs, all we do is to define the message flow and configure various endpoints and other characteristics of the application. So Camel applications are highly configurable by design. When all the various options are externalized using properties component, it is possible to configure an application for different expectations and redeploy without touching the actual source code at all. Camel is so configurable that you can change an endpoint with another one(for example replace HTTP endpoint with JMS) without changing the application code at all which we will cover next.

6. 高可配置性。 对同一程序应该通过简单的配置就可以达到高可用性,应该很容易扩展来达到可靠性或提高吞吐量,或者换句话说: 通过配置就可以拥有不同程度的自由。当使用DSL创建了一个Camel应用时,我们做的全部工作就是定义消息流,配置各种终端还有配置应用的其它特性。所以说Camel应用被设计的高度可配置化。当所有这些选项都被外化到配置组件之后,就可以按照期望来配置和重新部署应用,根本无需碰触源代码。Camel是如此的可配置化,你甚至不修改任何程序代码就可以用一个终端来替换另一个(比如用JMS来替换HTTP终端),这一点我们下面会讲到。

7. With smart endpoints. Micro services favour RESTish protocols and lightweight messaging rather than Web Services. Camel favors anything. It has HTTP support as no other framework.It has components for Asynchronous HTTP, GAE URL fetch service, Apache HTTP Client, Jetty, Netty, Servlet, Restlet, CXF and multiple data formats for serializing/deserializing messages. As for the queuing support, OOTB there are connectors for JMS, ActiveMQ, ZeroMQ, Amazon SQS, Amazon SNS, AMQP, Kestrel, Kafka, Stomp, you name it.

8. Testable. There is no common view on this characteristic. Some favor no testing at all and relying on business metrics. Some cannot afford to have bad business metrics ever. I like TDD and for me having the ability to test my business POJOs in isolation from the actual message flow, then test the flow separately by mocking some of the external endpoints is invaluable. Camel testing support can intercept and mock endpoints, simulate events, verify expectations with ease. Having a well tested individual microservice is the only guarantee to have the whole system to work as expected.

7. 具有智能终端。 微服务更倾向于使用REST风格的协议和轻量级消息机制,而不是使用Web Services。Camel则什么都支持。它不需要其它框架就可以支持HTTP。它有这种组件,比如异步HTTP, GAE URL获取服务, Apache HTTP Client, Jetty, Netty, Servlet, Restlet, CXF以及用多种数据格式对消息进行序列化/反序列化。关于队列方面的支持情况,有各种开箱即用的连接器,比如JMS, ActiveMQ, ZeroMQ, Amazon SQS, Amazon SNS, AMQP, Kestrel, Kafka, Stomp, 你能叫上名字的都有。

8. 可测试化。 关于这一特性没有一个特别统一的看法。有些人倾向于根本不做测试而依赖于业务指标。有些人则压根儿不能忍受出现糟糕的业务指标。我喜欢TDD(测试驱动开发),喜欢能够不依赖于实际的消息流就可以测试我的业务POJO,这样通过模拟外部终端来测试消息流就没有什么价值了。Camel在测试方面可以支持拦截和模拟终端、模拟事件、轻松的对期望结果进行验证。拥有经过良好测试的微服务,是使得整个系统能够正常运转的唯一保障。

9. Provisioned individually.The most important characteristics of microservices is that they run in isolation from other services most commonly as standalone Java applications. Camel can be embedded in Spring, OSGI or web containers. Camel can also run as a standalone Java application with embedded Jetty endpoints easily. But managing multiple processes, all running in isolation without a centralized tool is a hard job. This is what Fabric8[8] is made for. Fabric8 is developed by the same guys who developed Camel and supported by Red Hat JBoss. It is a poly Java application provisioning and management tool that can deploy and manage a variety of Java containers and standalone processes. To find out more about Fabric8, here is [9] nice post by Christian Posta.

9. 单独供应。微服务的最重要的特性是,服务是彼此隔离运行的,而且通常都是作为独立Java应用来运行。Camel可以嵌入到Spring,OSGI或者web容器中去。当然Camel也可以内置一个Jetty终端,然后作为一个独立的Java应用来运行。但是没有一个集中式的管理工具的话,管理多个独立运行的应用可是个棘手的差事。而这正是开发出Fabric8[8]的原因。Fabric8是由开发Camel的同一帮人开发的,并且由Red Hat JBoss来维护。它是一个复合的Java应用供应和管理工具,可以部署和管理多种Java容器和独立的进程。想要深入了解Fabric8的话,可以参考注释[9],它是Christian Posta写的一篇不错的文章。

10. Language neutral. Having small and independently deployed applications allow developers to choose thebest suited languagage for the given task. Camel has XML, Java, Scala, Groovy and few other DSLs with similar syntax and capabilities .But if you don't want to you use Camel at all for a specific micro service, you can still use Fabric8 do deploy and manage applications written in other languages and run them as native processes [10].

In summary: Microservices are not strictly defined and that's the beauty. It is a lightweight style of implementing SOA that works. So is Apache Camel. It is not a full featured ESB, but it can be as part of JBoss Fuse. It is not a strictly defined specification driven project, but a lightweight tool that works and developers love it.

References

[1] Micro­Service Architecture, by Fred George (video) https://www.youtube.com/watch?v=2rKEveL55TY

[2] Micro­Services ­ Java, the UNIX way, by James lewis (video) http://jz13.java.no/presentation.html?id=2a7b489a

[3] Microservices, by Martin Fowler http://martinfowler.com/articles/microservices.html

[4] μCon: The Microservices Conference https://skillsmatter.com/conferences/6312­mucon

[5} Nanoservices http://arnon.me/wp­content/uploads/2010/10/Nanoservices.pdf

[6] Hawtio http://hawt.io/

[7] Circuit Breaker Pattern in Apache Camel by Bilgin Ibryam http://www.ofbizian.com/2014/04/circuit­breaker­pattern-in­apache­camel.html

[8] Fabric8 http://fabric8.io/

[9] Meet Fabric8: An open­source integration platform by Christian Posta http://www.christianposta.com/blog/?p=376

[10] Micro Services the easy way with Fabric8 by James Strachan http://macstrac.blogspot.co.uk/2014/05/micro-services­with­fabric8.html

10. 语言中立性。 采用小而独立部署的应用模式,使得开发者可以针对特定任务采用最合适的语言。Camel以特定的语法和能力支持 XML, Java, Scala, Groovy和其它一些DSL(领域特定语言)。但是如果你在处理一个微服务时根本不想使用Camel的话,你仍然可以使用Fabric8来部署和管理那些其它语言编写的应用程序,并以本地进程的方式来运行它们。

总结: 微服务没有一个严格的定义,而这恰是一种美。它是一种轻量级的实现SOA的方式,而且很好用。Apache Camel也是如此。它不支持ESB的全部特性,不过它可以作为JBoss Fuse的一部分。Apache Camel不是一个由严格定义的规范来驱动的项目,而是一个轻量级的工具,而且开发者们爱它。

参考资料

[1] Micro­Service Architecture, by Fred George (video) https://www.youtube.com/watch?v=2rKEveL55TY

[2] Micro­Services ­ Java, the UNIX way, by James lewis (video) http://jz13.java.no/presentation.html?id=2a7b489a

[3] Microservices, by Martin Fowler http://martinfowler.com/articles/microservices.html

[4] μCon: The Microservices Conference https://skillsmatter.com/conferences/6312­mucon

[5} Nanoservices http://arnon.me/wp­content/uploads/2010/10/Nanoservices.pdf

[6] Hawtio http://hawt.io/

[7] Circuit Breaker Pattern in Apache Camel by Bilgin Ibryam http://www.ofbizian.com/2014/04/circuit­breaker­pattern-in­apache­camel.html

[8] Fabric8 http://fabric8.io/

[9] Meet Fabric8: An open­source integration platform by Christian Posta http://www.christianposta.com/blog/?p=376

[10] Micro Services the easy way with Fabric8 by James Strachan http://macstrac.blogspot.co.uk/2014/05/micro-services­with­fabric8.html

返回顶部
顶部