Google Cloud 通用数据库构建4 – Kubernetes & SpringBoot & Apache Camel第1部分

我们团队正在设计采用微服务架构的下一代后端,在全公共云上。

情况

上次我创建了一个SpringBoot应用程序并将其打包为Docker镜像,然后在GKE上进行了部署。但为了实现持久化存储,我需要创建一个Web服务。虽然我认为可以使用任何工具来创建该服务,但个人而言,我很喜欢Apache Camel。

在日本,它似乎没有太普及,但它是EIP的实现,可以通过重用各种组件来构建服务。它的代码量非常少。这次我不打算深入研究Camel,而是着重集成到SpringBoot应用程序中。

pom.xml -> 自行内容修改

将所需的库导入pom.xml文件。由于进行了完整可执行JAR打包,所以这些库都包含在一个JAR文件中。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>jp.co.yahoo.zeolite.agent</groupId>
    <artifactId>storeagent</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>war</packaging>

    <name>storeagent</name>
    <description>Spring Boot Application</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.3.6.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <camel-ver>2.17.1</camel-ver>
    </properties>

    <dependencies>

        <!-- Spring Boot -->

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jetty</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!-- Apache Camel -->

        <dependency>
            <groupId>org.apache.camel</groupId>
            <artifactId>camel-core</artifactId>
            <version>${camel-ver}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.camel</groupId>
            <artifactId>camel-restlet</artifactId>
            <version>${camel-ver}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.camel</groupId>
            <artifactId>camel-spring-boot</artifactId>
            <version>${camel-ver}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.camel</groupId>
            <artifactId>camel-swagger-java</artifactId>
            <version>${camel-ver}</version>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>1.3.6.RELEASE</version>
                <configuration>
                    <mainClass>jp.co.yahoo.zeolite.agent.StoreagentApplication</mainClass>
                    <layout>WAR</layout>
                    <executable>true</executable>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

主要添加的库如下。

    • spring-boot-starter-jetty

組み込みtomcat→組み込みjettyにコンテナを切り替え。

spring-boot-starter-thymeleaf

可視化のためのtoolも作ろうと思うので、テンプレートエンジンにthymeleaf(タイムリーフ)

camel-core

Apache Camelのコアライブラリ

camel-restlet

restAPI作成に使用します。他にいくつかCamelコンポーネントがあるが、今回はこれを使用。

camel-swagger-java

api-docを作ってくれるのが嬉しい。

API Gatewayや、Apigeeとつなぐ際にも便利。今後はこれがrest定義のスタンダードになりそうですね。

camel-spring-boot

Apache CamelのSpringBootサポート

路線的定義

正如前面所述,Apache Camel将各个Camel组件组合起来构建应用程序。这些组件主要集中在官方网站上。通过重写RouteBuilder类的configure方法,我们可以按照下面的方式实现称为Camel Route的流程。

from("jetty:https://0.0.0.0/myapp/").to("bean:myBean?method=methodName");

例如,在这种情况下,可以启动一个可以通过localhost:80/myapp访问的webservice(本质上只是启动了一个嵌入式jetty)。
头部信息和正文信息将绑定到消息中,并几乎原封不动地传递给通过to()方法调用的组件。(在这种情况下,使用了bean组件,因此将传递给在上下文中注册的myBean实例的methodName方法)

本次使用camel-spring-boot来实现,提供了一个继承自RouteBuilder类的FatJarRouter类。

只需要一种选项。将Spring Boot应用程序的启动类继承FatJarRouter类即可。

@SpringBootApplication
@ComponentScan("jp.co.yahoo.zeolite")
public class StoreagentApplication extends FatJarRouter {

    public static void main(String[] args) {
        SpringApplication.run(StoreagentApplication.class, args);
    }

    @Override
    public void configure() throws Exception {

        //handling Exceptions.
        onException(Exception.class)
                .handled(true)
                .setBody(exceptionMessage().prepend("{\"error\":\"").append("\"}"))
                .convertBodyTo(String.class)
                .log(LoggingLevel.ERROR, "${body}")
                .to("direct:setWebserviceResponseHeaders")
                .setHeader(Exchange.HTTP_RESPONSE_CODE, constant(500));

        errorHandler(deadLetterChannel("direct:deadlog").maximumRedeliveries(0));

        from("direct:deadlog").routeId("DEAD_LOG").log(LoggingLevel.ERROR, "${body}");

        from("direct:setWebserviceResponseHeaders")
                .routeId("SET_WEB_HEADERS")
                .setHeader(Exchange.CONTENT_TYPE,
                        constant("application/json; charset=utf-8"));

        //Rest Configurations.
        restConfiguration().component("restlet")
                .enableCORS(true)
                .apiContextPath("/api-docs")
                .apiProperty("api.title", "Zeolite StoreAgent APIs")
                .apiProperty("api.version", "1.0.0")
                .apiProperty("cors", "true")
                .contextPath("/service").host(InetAddress.getLocalHost().getHostName()).port(21001)
                .dataFormatProperty("prettyPrint", "true")
                .bindingMode(RestBindingMode.off)
                .componentProperty("disableStreamCache", "true");

        //Rest API
        rest("/upsert")
                .description("Upsert API. 対象ItemをUpsertします。")
                .produces("application/json").consumes("application/json")
                .post().description("upsert the item.")
                .param().name("itemKey").type(RestParamType.header).description("The key of an item.").dataType("string").endParam()
                .param().name("item").type(RestParamType.body).description("The item to store.").dataType("string").endParam()
                .responseMessage().header("http Status code").endResponseHeader().endResponseMessage()
                .to("direct:upsert");

        from("direct:upsert")
                .setBody(constant("{\"message\" : \"OK!\"}"))
                .to("mock:upsert");



    }
}

由于本次还使用了camel-swagger,因此在规范文档中一并写入所需的注释,具体如下所示。

        //Rest API
        rest("/upsert")
                .description("Upsert API. 対象ItemをUpsertします。")
                .produces("application/json").consumes("application/json")
                .post().description("upsert the item.")
                .param().name("itemKey").type(RestParamType.header).description("The key of an item.").dataType("string").endParam()
                .param().name("item").type(RestParamType.body).description("The item to store.").dataType("string").endParam()
                .responseMessage().header("http Status code").endResponseHeader().endResponseMessage()
                .to("direct:upsert");

只需通过Maven启动即可。尝试使用Postman发送请求。

スクリーンショット 2016-11-14 22.03.01.png

正常地回来了。

另外,还可以尝试使用Camel Swagger。
有关Swagger的信息,请参考下面的内容。

    • swagger

 

    camel-swagger

在默认情况下,camel-swagger会在/api-docs上创建定义文件。
在这种情况下,访问http://localhost:21001/service/api-docs,将返回定义文档。
将其提供给SwaggerUI或连接的APIGateway等,非常方便。

スクリーンショット 2016-11-14 22.09.36.png

一种感觉

只需要这么少的代码,就可以启动带有定义文档的REST API。而且HTTP的header和body会直接绑定到Message的header和body,非常方便。

最令人高兴的是可以重复使用有成就的事物。

以前,我们自己创建了一个叫做CamelBoot的类,用FullExecutable来实现机动性,但随着SpringBoot的推出,这一切都变得不再需要了。只需要一个jar文件进行启动,无需任何启动脚本。只需放置并运行即可。因此,它与Docker也非常兼容。无论是在Mac还是在Windows上进行开发,都可以通过IDE进行开发,并通过maven直接启动和调试。
在我心中,它已经成为了一种稳定的架构。
如果了解这些,它将成为在紧急情况下拯救项目的强大武器。

我已经多次得到救助。
基本上,无论遇到何种情况,我都能够在短时间内通过使用SpringBoot+ApacheCamel+Thymeleaf+Commons等工具来解决。

因为是POJO,所以更容易外包。
为什么不流行一些呢…

下次

要不要深入探讨一下上述内容呢?

广告
将在 10 秒后关闭
bannerAds