vlambda博客
学习文章列表

读书笔记《cloud-native-applications-in-java》云-本机应用程序运行时

Chapter 7. Cloud-Native Application Runtime

使用 Jenkins 等部署管道开发、测试和部署应用程序后,在本章中,我们将研究运行应用程序或服务的运行时生态系统。我们将涵盖以下主题:

  • The need for a comprehensive runtime, including a recap of the problems in operating and managing a large number of services
  • Implementing the reference runtime architecture, including:
    • Service registry
    • Config server
    • Service frontends, API gateway, reverse proxy, and load balancer
    • A look at Zuul as a reverse proxy
    • Container management and orchestration through Kubernetes and Minikube
  • Running on Platform as a Service (PaaS):
    • How the PaaS platforms help realize service runtime reference architecture that we discussed in previous chapter
    • Installing Cloud Foundry and running our product service on the Cloud Foundry

The need for a runtime


我们已经开发了我们的服务,为它们编写了测试,自动化了持续集成,并在容器中运行它们。我们还需要什么?

在生产中大规模运行许多服务并不容易。随着更多服务在生产中发布,它们的管理开始变得复杂。因此,这里是对微服务生态系统中讨论并在前一章的一些代码示例中解决的问题的回顾:

  • Service running in the cloud: A traditional large application was hosted on an application server and ran at an IP address and port. On the other hand, microservices run in multiple containers at various IP addresses and ports so the tracking production service can get complex.
  • Services come up and go down like moles in a Whack-a-Mole game: There are 100s of services with their loads balanced and failover instances running all over the cloud space. Many teams, thanks to DevOps and agility, are deploying new services and taking down old services. Thus, as we can see, a microservice-driven cloud environment is very dynamic. These two issues are addressed by the service registry tracking the services. So, the clients can look up where the services corresponding to a name are running using a client-side load balancing pattern. However, if we want to abstract the clients from the look up, then we use the pattern of server-side load balancing, where a load balancer, such as Nginx, an API gateway like Apigee, or reverse proxy or router, such as Zuul, abstracts the clients from the actual address of the services.
  • Managing my configuration across microservices: If the deployment unit has broken into multiple services, so has the property file containing the packaged configuration items such as connection addresses, user ID, logging levels, and so on. So, if I have to change a logging level for a set of services or a flow, do I have to change it across all the application's property files? Here, we will see how centralizing the property files in a config server like Spring Config Server or Consul helps to manage the properties in a hierarchical fashion.
  • So many log files to handle: Each microservice is generating one (or more) log files like .out and .err and Log4j files. How do we search for log messages across multiple log files from multiple services? The pattern to solve this is log aggregation, implemented with commercial tools such as Splunk or open source tools like Logstash or Galaxia. They are also present by default in PaaS offerings like Pivotal Cloud Foundry. The other option is to stream logs to the aggregators such as Kafka from where they can be centrally stored.
  • Metrics from each service: In Chapter 2, Writing Your First Cloud-Native Application, we added Spring actuator metrics, which are exposed as endpoints. There are many other metrics, such as Dropwizard metrics, that can be captured and exposed.Either an agent has to monitor all services actuator metrics, or they can be exported and then aggregated in a monitoring and reporting tool. Another option is for application monitoring tools like Dynatrace, AppDynamics to monitor application, and extract metrics at Java level. We will take a look at these in the next chapter.

Implementing runtime reference architecture


以下参考运行时架构解决了上一节中讨论的问题:

读书笔记《cloud-native-applications-in-java》云-本机应用程序运行时

所有这些组件都已在第 1 章中讨论过, 云原生简介。现在,我们继续选择技术并展示一个实现。

Service registry

第 2 章编写您的第一个云原生中讨论了运行服务注册表 Eureka应用程序。请参阅该章节以刷新您对 product 服务如何向 Eureka 注册自身以及客户端如何使用 Ribbon 和 Eureka 查找 产品的记忆 服务。

如果我们使用 Docker 编排,例如 Kubernetes,服务注册的重要性会稍微降低。在这种情况下,Kubernetes 自己管理服务的注册,代理查找并重定向到该服务。

Configuration server

配置服务器以分层方式存储配置。这样,应用程序只需要知道配置服务器的地址,然后连接到它就可以获取剩余的配置。

有两个流行的配置服务器。一个是 Hashicorp 的 Consul,另一个是 Spring Config Server。我们将使用 Spring Config Server 来保持堆栈与 Spring 一致。

让我们回顾一下开始使用配置服务器的步骤。使用外部化配置有两个部分:服务器(服务属性)和客户端。

The server part of the config server

有许多选项可以通过 HTTP 连接提供属性, 领事和动物园管理员很受欢迎。但是,对于 Spring 项目,Spring Cloud 提供了一个灵活的配置服务器,可以连接到多个后端,包括 Git、数据库和文件系统。鉴于属性最好存储在版本控制中,我们将在此示例中使用用于 Spring Cloud Config 的 Git 后端。

Spring Cloud Config 服务器代码、配置和运行时与 Eureka 非常相似,并且很容易像我们在 Chapter 中为 Eureka 所做的那样启动实例2编写您的第一个云原生应用程序

按照以下步骤运行服务注册表:

  1. Create a new Maven project with the artifact ID set to config-server.
  2. Edit the POM file and add the following:

1.父为spring-boot-starter-parent

2.依赖 as spring-cloud-config-server

3.依赖管理 as spring-cloud-config

读书笔记《cloud-native-applications-in-java》云-本机应用程序运行时
  1. Create an ConfigServiceApplication class that will have annotation to start the config server:
读书笔记《cloud-native-applications-in-java》云-本机应用程序运行时
  1. Create an application.yml file in the config-server/src/main/resources folder of the application and put the following:
server: 
  port: 8888 
spring: 
  cloud: 
    config: 
      server: 
        git: 
          uri: file:../.. 

端口号是配置服务器通过 HTTP 连接侦听配置请求的位置。

spring.cloud.config.server.git.uri的另一个属性是Git的位置,我们已经为开发配置了一个本地文件夹。这是 Git 应该在本地机器上运行的地方。如果没有,请在此文件夹上运行 git init 命令。

我们在这里不涉及 Git 身份验证或加密。请查看 Spring Cloud 配置手册(https://spring.io/guides /gs/centralized-configuration/) 了解更多详情。

  1. In the product.properties file, we will hold the properties that were initially held in the application.properties file of the actual product project. These properties will be loaded by the config server. We will start with a small property, as follows:
testMessage=Hi There 

该属性文件应该存在于我们在上一步中刚刚引用的 Git 文件夹中。请使用以下命令将属性文件添加到 Git 文件夹:

git add product.properties and then commit.
  1. Create a bootstrap.yml file in the resources folder of application and input the name of this project:
spring: 
  application: 
    name: configsvr 
  1. Build the Maven project and then run it.
  2. You should see a Tomcat started message, as follows:
读书笔记《cloud-native-applications-in-java》云-本机应用程序运行时

ConfigurationServiceApplication 已启动并正在侦听端口 8888

让我们检查一下我们添加的属性是否可供消费。

启动浏览器并检查 product.properties。有两种方法可以做到这一点。第一种是将属性文件视为 JSON,第二种是将其视为文本文件:

  1. http://localhost:8888/product/default:
读书笔记《cloud-native-applications-in-java》云-本机应用程序运行时
  1. http://localhost:8888/product-default.properties:
读书笔记《cloud-native-applications-in-java》云-本机应用程序运行时

如果您想知道,默认值是配置文件名称。 Spring Boot 应用程序支持配置文件覆盖,例如,用于测试和 用户验收测试 (UAT ) 环境,其中生产属性可以替换为 product-test.properties 文件。因此,配置服务器支持以下形式的 URL 读取:http://configsvrURL/{application}/{profile}http:// /configsvrURL/{application-profile}.properties.yml

在生产中,我们不太可能直接访问配置服务器,如前所示。将是访问配置服务器的客户端;我们将在接下来看到这一点。

The config client

我们将使用之前开发的 product 服务代码作为基线,开始将应用程序中的属性提取到配置服务器中。

  1. Copy the product service project from eclipse to create a new project for this chapter.
  2. Add the spring-cloud-starter-config dependency to the list of the dependencies in the POM file:
读书笔记《cloud-native-applications-in-java》云-本机应用程序运行时
  1. Our main work will be on the resources. Tell the product service to use the config server running at: http://localhost:8888. The failFast flag indicates that we do not want the application loading to continue if we don't find the config server. This is important, as it will ensure that the product service should not assume defaults if it does not find the config server:
spring: 
  application: 
    name: product 
 
  cloud: 
    config: 
      uri: http://localhost:8888 
      failFast: true 
  1. Shift all properties in the application.properties section of the resources folder of the product service to the product.properties that we had defined as part of the git folder loaded by the config server in the previous section. Your product.properties file will now have useful configuration, in addition to the Hi There message that we had put in for testing:
server.port=8082 
eureka.instance.leaseRenewalIntervalInSeconds=15 
logging.level.org.hibernate.tool.hbm2ddl=DEBUG 
logging.level.org.hibernate.SQL=DEBUG 
testMessage=Hi There 
  1. We can now delete the application.properties file that is present in the resources folder of the product service.
  2. Let's add a test method to our product service to check the property being set from the config server:
    @Value("${testMessage:Hello default}") 
    private String message; 
    
   @RequestMapping("/testMessage") 
   String getTestMessage() { 
         return message ; 
   }
  1. Fire up the Eureka server, as done in the previous chapters.
  2. Ensure the config server from the previous section is still running.
  3. Now, start the product service from the ProductSpringApp main class. Right at the beginning of the logs, you will see the following statements:
读书笔记《cloud-native-applications-in-java》云-本机应用程序运行时

当 ProductSpringApp 启动时,它首先从运行在 8888 端口上的外部配置服务获取配置

name=product 的环境在 bootstrap.yml 文件中被选为我们的应用程序名称。

product 服务应该监听的端口号是从这个配置服务器中获取的,以及其他属性,例如我们现在将看到的测试消息:

读书笔记《cloud-native-applications-in-java》云-本机应用程序运行时

ProductSpringApp 开始于端口 8082 从外部化配置中获取。

使用两个 URL 测试应用程序,如下所示:

  • http://localhost:8082/testMessage: This returns Hi There, which was our configured message

Note

运行其他 REST 服务之一,例如产品视图。您将看到所需的产品信息,以表明我们的服务运行良好。

  • http://localhost:8082/product/1: This will return {"id":1,"name":"Apples","catId":1}

Refreshing the properties

现在,如果您想要集中反映在所有服务上的属性发生变化怎么办?

  1. You can change the message in the product.properties file to a new message, such as Hi Spring.
  2. You will notice that the config server picks up this change on the next read, as follows:
读书笔记《cloud-native-applications-in-java》云-本机应用程序运行时

但是,服务不会立即获取此属性,因为调用 http://localhost:8082/testMessage 会导致旧的 Hi There 消息。我们如何在命令行刷新属性?

这就是执行器命令 /refresh 派上用场的地方。我们将bean配置为 的一部分@RefreshScope 注释。当从 Postman 应用程序执行对 http://localhost:8082/refreshPOST 方法调用时,这些 bean 将被重新加载.请参阅以下日志以检查调用刷新导致重新加载属性的情况:

读书笔记《cloud-native-applications-in-java》云-本机应用程序运行时

第一行在日志中显示 product 服务如何在执行 http://localhost:8082/refresh 时刷新其属性

您可以检查,在标记的行之后,属性加载如何重新开始,以及调用 http://localhost:8082/testMessage 后的消息如何得到反映。

The microservice frontend

使用反向代理、负载均衡器、边缘网关或 API 网关来前端微服务是一种流行的模式,其复杂性逐渐增加。

  • Reverse proxy: A reverse proxy is defined as a process that makes the downstream resource available as though it originated from itself. In that respect, the webserver frontend and the application server also act as reverse proxies. The reverse proxy is useful in cloud-native applications, as it ensures that the clients do not need to look up services and then access them like we did in Chapter 2, Writing Your First Cloud-Native Application. They have to access the reverse proxy, which looks up the microservices, calls them, and makes the response available to the client.
  • Load balancer: The load balancer is an extended form of reverse proxy that can balance the request it receives from clients across multiple services. This increases the availability of the services. The load balancer can work with service registry to find out which are the active services and then balance the requests between them. Nginx and HAProxy are good examples of load balancers that can be used to frontend microservices.
  • Edge gateway: As the name implies, the edge gateway is a higher-order component that is deployed on the edge of the enterprise or division and has more capabilities than a load balancer, such as authentication, authorization, traffic control, and routing functions. Netfix Zuul is a good example of this pattern. We will cover code examples of using Zuul in this section.
  • API gateway: With the popularity of Mobile and APIs, this component provides more complex capabilities, such as fanning out requests to multiple services doing orchestration between them, intercepting and enhancing the requests or responses or converting their formats, doing sophisticated analysis on the requests. It is also possible to use both an API gateway and a load balancer, reverse proxy, or edge in a single flow. This approach helps with the segregation of responsibilities, but also adds latency due to an additional hop. We will see API gateway in later chapters.

Netflix Zuul

Netflix Zuul 是一种流行的边缘网关,由 Netflix 推广,然后作为 Spring Cloud 的一部分提供。 Zuul 表示看门人并执行所有这些功能,包括身份验证、流量控制,以及最重要的路由,如前所述。它在查找服务和报告指标方面与 Eureka 和 Hystrix 很好地集成在一起。企业或域中的服务可以通过 Zuul 进行前端。

让我们在我们的 product 服务前面放置一个 Zuul 网关:

  1. Create a new Maven project and set its artifact ID as zuul-server.
  2. Edit the POM file and add the following:

1.设置父级为spring-boot-starter-parent

2、设置对spring-cloud-starter-zuul-eureka的依赖-web 项目

3.在spring-cloud-starter-netflix上设置依赖管理:

读书笔记《cloud-native-applications-in-java》云-本机应用程序运行时
  1. Create an application class with an annotation to enable Zuul Proxy:
读书笔记《cloud-native-applications-in-java》云-本机应用程序运行时

application.yml 中的配置信息对于 Zuul 来说非常关键。这是我们配置 Zuul 的路由功能以将其重定向到正确的微服务的地方。

  1. Since Zuul interacts well with Eureka, we will leverage that to our advantage:
eureka: 
  client: 
    serviceUrl: 
defaultZone: http://127.0.0.1:8761/eureka/ 

这告诉 Zuul 在该端口上运行的 Eureka 注册表中查找服务。

  1. Configure the port to listen at 8080.
  2. Finally, configure the routes. These are the mappings of the URL in the REST request to the respective service that can handle it:
zuul: 
  routes: 
    product: 
      path: /product*/** 
      stripPrefix: false 

What happens behind the scenes

让我们看看幕后发生了什么:

  1. The product section in the route definition tells Zuul that the paths configured after /product*/** are to be redirected to the product service, if it is present in the Eureka registry configured in the Zuul server.
  2. The path is configured to be /product*/**. Why three * ? If you remember, our product service can handle two types of REST services: /product/1 GET and /product PUT, DELETE, POST requests. The /products?id=1 GET requests that it return a list of products for the given category ID. Hence, the product* maps to both /product and /products in the URL.
  3. The false setting of stripPrefix lets the /product/ pass on to the product service. If the flag is not set, then only the rest of the URL after /product*/ will be passed on to the microservice. Our product microservice has mapping including the /product, hence we want the prefix to be preserved when forwarding to the product service.

Running them all at once

现在让我们尝试运行我们的 product 服务以及生态系统的其他部分:

  1. Start the services in the reverse order of dependency.
  2. Start the config server and the Eureka server by running the main class of the projects or through Maven.
  3. Start the product service.
  4. Start the Zuul service. Watch the log windows and wait till all servers start.
  5. Now, run the following requests in your browser:
    • http://localhost:8080/product/3
    • http://localhost:8080/products?id=1

您应该会在第一个请求中看到产品 3 以及在第二个请求中与类别 1 对应的产品。

我们看一下Zuul和product服务的日志:

  • In Zuul, you can see that the mapping of the /product*/** was resolved and the endpoint to the product service was fetched from the Eureka registry:
读书笔记《cloud-native-applications-in-java》云-本机应用程序运行时

Zuul edge 现在注册为 product 服务的请求映射,并转发到 Eureka 指向的服务地址

  • In the product service, the service execution has happened by running the queries on the database:
读书笔记《cloud-native-applications-in-java》云-本机应用程序运行时

Kubernetes – container orchestration


到目前为止,我们已经单独部署了 Eureka、配置服务器、product 服务和 Zuul 等服务。

回顾上一章,我们可以通过 CI 来自动化他们的部署,比如 Jenkins。我们还看到了如何使用 Docker 容器完成部署。

但是,在运行时,容器仍然彼此独立运行。没有一种机制可以扩展容器,或者如果容器失败则重新启动它们。此外,在哪个 VM 上部署哪个服务的决定是手动的,这意味着服务总是被部署到为服务运行而指定的静态 VM 上,而不是智能地混合和匹配。简而言之,缺少管理我们的应用程序服务的编排层。

Kubernetes 是一种流行的编排机制,它使部署和运行时管理变得更容易。

Kubernetes architecture and services

Kubernetes 是一个由谷歌牵头的开源项目。它试图实现一些在其自己的称为 Borg 的内部容器编排系统中实施的经过验证的想法。 Kubernetes 架构由两个组件组成:主节点和从节点。主节点具有以下组件:

  • Controller: To manage the nodes, replicas, and services
  • API Server: To provide REST endpoints used by the kubectl client and the minion nodes
  • Scheduler: To decide where a particular container must be spawned
  • Etcd: To store the state of the cluster and configurations

Minion 节点包含两个组件:

  • Kubelet: An agent to communicate resource availability to the master and launch the containers specified by the scheduler
  • Proxy: To route network requests to the kubernetes services
读书笔记《cloud-native-applications-in-java》云-本机应用程序运行时

Kubernetes 是一个容器调度器,它使用两个原语,即 Pod 和 Service。 Pod 是相关容器的集合,可以使用某些标签进行标记;服务可以使用这些标签来定位 Pod 并公开端点。下图说明了这个概念:

读书笔记《cloud-native-applications-in-java》云-本机应用程序运行时

Pod 在 kubernetes 中被认为是短暂的,可能会被杀死。但是,如果 Pod 是使用 ReplicaSet 创建的,我们可以在其中指定某个 Pod 的副本或实例必须存在于系统中,那么 kubernetes 调度程序将自动调度 Pod 的新实例,一旦 Pod 可用,服务将开始将流量路由到它。您可能会注意到,只要标签匹配,一个 Pod 可能会成为多个服务的目标,此功能对于滚动部署很有用。

我们现在将看看如何在 Kubernetes 上部署一个简单的 API 并进行滚动升级。

Minikube

Minikube 是一个有助于在虚拟机上运行工作的单节点 Kubernetes 的项目。

您可以按照以下说明安装 Minikube: https://github.com/kubernetes/ minikube

对于 Windows,请确保已完成以下步骤:

Running product service in Kubernetes

让我们将现有的 product 服务更改为通过 Kubernetes 容器编排运行:

读书笔记《cloud-native-applications-in-java》云-本机应用程序运行时
  1. You can test if the configuration is working by running it, as shown in the following screenshot:
读书笔记《cloud-native-applications-in-java》云-本机应用程序运行时
  1. Set up the Docker client to connect to the Docker daemon running within the Minikube VM as follows:
读书笔记《cloud-native-applications-in-java》云-本机应用程序运行时
  1. Build the Docker image from the instructions in the previous chapters where we created a Docker image as follows:
读书笔记《cloud-native-applications-in-java》云-本机应用程序运行时
  1. Create a deployment file (note that the imagePullPolicy is set to never, because otherwise, the default behavior of Kubernetes is to pull from the Docker registry):
读书笔记《cloud-native-applications-in-java》云-本机应用程序运行时
  1. Verify that the three instances are running:
读书笔记《cloud-native-applications-in-java》云-本机应用程序运行时
  1. Create a service.yml file, so that we can access the Pods:
读书笔记《cloud-native-applications-in-java》云-本机应用程序运行时

现在,运行 service.yml 文件,如下所示:

读书笔记《cloud-native-applications-in-java》云-本机应用程序运行时

现在,您可以获得服务的地址:

读书笔记《cloud-native-applications-in-java》云-本机应用程序运行时

您现在可以访问 API,它将请求路由到所有三个 Pod:

读书笔记《cloud-native-applications-in-java》云-本机应用程序运行时

您可以对单个命令使用 -v 以获取以下详细信息:

读书笔记《cloud-native-applications-in-java》云-本机应用程序运行时
  1. Change the code, as follows:
读书笔记《cloud-native-applications-in-java》云-本机应用程序运行时
  1. Build Docker image with a new tag:
读书笔记《cloud-native-applications-in-java》云-本机应用程序运行时
  1. Update the deployment.yml file:
读书笔记《cloud-native-applications-in-java》云-本机应用程序运行时
  1. Apply the change:
读书笔记《cloud-native-applications-in-java》云-本机应用程序运行时

Platform as a Service (PaaS)


云原生应用程序的另一个流行运行时是使用 PaaS 平台,特别是应用程序 PaaS 平台。 PaaS 提供了一种部署云原生应用程序的简单方法。它们提供附加服务,如文件存储、加密、键值存储和数据库,可以轻松绑定到应用程序。 PaaS 平台还提供了一种简单的机制来扩展云原生应用程序。现在让我们了解为什么 PaaS 平台为云原生应用程序提供出色的运行时。

The case for PaaS

在运行时架构实现中,我们看到配置服务器、服务注册中心、反向代理、监控、日志聚合和指标等许多组件必须结合在一起才能实现可扩展的微服务架构。  ProductService中的业务逻辑除外,其余的服务和组件都是纯配套组件,涉及大量的平台搭建和工程。

如果我们构建的所有组件都在作为服务提供的平台中开箱即用怎么办?因此,PaaS 是对容器编排的更高层次的抽象。 PaaS 提供了我们在容器编排中讨论过的所有基础基础设施服务,例如重启服务、扩展服务和负载均衡,开箱即用。此外,PaaS 还提供额外的服务来补充云原生应用程序的开发、扩展和维护。这种方法有一个权衡,它减少了选择和微调组件的选择。然而,对于大多数专注于业务问题的企业来说,这将是一个很好的权衡。

因此,有了 PaaS,开发人员现在可以专注于编写代码,而不必担心他/她将要部署的基础设施。所有的工程现在都变成了开发人员和运营团队可以配置的配置。

读书笔记《cloud-native-applications-in-java》云-本机应用程序运行时

PaaS 的其他几个优点包括:

  • Runtimes: Providing various runtimes for developer to develop services, such as Java, Go, Node.js, or .NET. Thus, the developer focuses on generating a deployment, which can run in the various runtimes provided by the PaaS environment.
  • Services: PaaS provides application services, such as databases and messaging out of the box for the applications to use. This is beneficial, as the developers and the operations do not have to install or manage them separately.
  • Multi-cloud: PaaS abstracts the developer from the underlying infrastructure (or IaaS). Thus, the developer can develop for the PaaS environment, without worrying about deploying it in a data center or to various cloud providers such as AWS, Azure, or the Google Cloud Platform, if the PaaS runs on these infrastructures. This avoids lock-in to an infrastructure or cloud environment.

PaaS 环境的权衡是它们可能会受到限制并降低灵活性。选择的默认服务和运行时可能不适合所有用例。但是,大多数 PaaS 提供商提供插件点和 API 以包含更多服务和配置,以及微调运行时行为的策略,这可以减轻权衡取舍。

Cloud Foundry

Cloud Foundry 是 Cloud Foundry 基金会拥有的最成熟的开源 PaaS 之一。

它主要由以下部分组成:

  • Application runtime: The foundation platform, where the developer deploys the application workloads like Java or Node.js applications. Application runtime provides for capabilities like application life cycle, application execution, and supporting functions, such as routing, authentication, platform services, including messaging, metrics, and logging.
  • Container runtime: The runtime abstraction where the containers run. This provides deployment, management, and integration of the containers on which the applications run, using Kubernetes as the base platform. It is based on project Kubo.
  • Application services: These are services like databases that the application binds to. Typically, they are provided by third-party providers.
  • Cloud Foundry components: There are a lot of them, such as BOSH (for container runtime), Diego (for application runtime), Bulletin Board System (BBS), NATS, Cloud Controller, and so on. However, these are responsible for providing various capabilities of PaaS and can be abstracted from the developers. They are of relevance and interest to the operations and infrastructure.

The concept of org, account, and space

Cloud Foundry 有一个精心设计的基于角色的访问控制RBAC ) 用于管理应用程序及其各种资源:

  • Org: This represents an organization, to which multiple users can be bound. An org shares the applications, service availability, resource quota, and plans.
  • User account: The user account represents an individual login that can act on the applications or operations in cloud foundry.
  • Space: Every application or service runs in a space that is bound to org and managed by a user account. An org has at least one space.
  • Roles and permissions: The users belonging to org have roles which can do restricted actions (or permissions). The details are documented at: https://docs.cloudfoundry.org/concepts/roles.html.
The need for implementations of Cloud Foundry

安装和运行 vanilla Cloud Foundry 涉及很多工程。因此,有许多使用 Cloud Foundry 作为基础并提供附加功能的 PaaS 实现,最流行的是 IBM 的 Bluemix、Redhat 的 OpenShift 和 Pivotal Cloud Foundry (PCF) 来自 Pivotal。

Pivotal Cloud Foundry (PCF)

Pivotal 的 Cloud Foundry 旨在提高开发人员的生产力和操作员的效率,并提供安全性和可用性。

尽管本书的读者可以自由选择基于 Cloud Foundry 的 PaaS 实现,但我们选择 Pivotal 有几个原因:

  • Pivotal has been behind Spring Framework, which we have used amply in the book. Pivotal's Cloud Foundry implementation has native support of the Spring Framework and its components, such as Spring Boot and Spring Cloud. Hence, the Spring Boot deployable that we create can be directly deployed to the application runtime of the Cloud Foundry and managed.
  • Pivotal's service marketplace is rich, covering most of the platform components by partners including MongoDB, PostgreSQL, Redis, and native support (Pivotal developed) services for MySQL and Cloud Cache.
  • Pivotal has been doing a number of releases in this space and hence the service offerings are updated frequently.

PCF components

Pivotal 网站 pivotal.io/platform 给出了一个非常简单的 Cloud Foundry 实现图,这映射到我们之前的讨论:

  • Pivotal Application Service (PAS): This is an abstraction for applications that map to application runtime in Cloud Foundry. Internally, it uses Diego, but that is hidden from the developer. PAS has excellent support for Spring Boot and Spring Cloud, but can run other Java, .NET, and Node apps as well. It is suitable for running custom written application workloads.
  • Pivotal Container Service (PKS): This is an abstraction for containers and maps to container runtime in Cloud Foundry. It uses BOSH internally. It is suitable for running workloads that are provided as containers, that is, independent service vendor (ISV) applications like Elasticsearch.
  • Pivotal Function Service (PFS): This is a new offering of Pivotal outside of the Cloud Foundry platform. It provides abstraction for functions. It promotes serverless computing. The functions are invoked on a HTTP request (synchronous) or when messages arrive (asynchronous).
  • Marketplace: This maps to the application services in Cloud Foundry. Given the popularity of the PCF, there are a lot of services available in the marketplace.
  • Shared components: These include the supporting services to run functions, applications, and containers, such as authentication, authorization, logging, monitoring (PCF watch), scaling, networking, and so on.
读书笔记《cloud-native-applications-in-java》云-本机应用程序运行时

PCF 可以在大多数流行的云上运行,包括托管在数据中心上的 Google Compute Platform、Azure、AWS 和 Open Stack (IaaS)。

虽然 PCF 及其组件非常适合服务器端负载,但对于在本地计算机上构建软件的开发人员来说可能很麻烦。我们现在正处于那个阶段。我们开发了 product 服务,并通过各个阶段成熟以达到云原生运行时。

整个 PCF 及其运行时组件很难安装在笔记本电脑上进行开发。

PCF Dev

PCF Dev 是一个精简的 PCF 发行版,可以在台式机或笔记本电脑上的 VM 上本地运行。它承诺启用与开发人员在主 PCF 环境中相同的环境,因此当适用于 PCF Dev 的应用程序在主 PCF 环境上运行时没有区别。参考 https://docs.pivotal.io/pcf 中的表格-dev/index.html 用于精确比较 PCF Dev 提供的大小和功能与完整的 PCF 和 Cloud Foundry< /span>(CF):

  • It supports the application runtime for Java, Ruby, PHP, and Python.
  • It has a mini version of PAS that gives the essential capabilities for our service development that we have discussed so far, such as logging and metrics, routing, Diego (Docker) support, application services, scaling, monitoring, and failure recovery.
  • It also comes with four application services built-in, these are: Spring Cloud Services (SCS), Redis, RabbitMQ, and MySQL.
  • However, it is not meant for production. It does not have BOSH, which orchestrates over the infrastructure layer.

如果您的台式机/笔记本电脑有超过 8 GB 的内存和超过 25 GB 的磁盘空间,让我们开始吧。

Installation

PCF Dev 可以在 Mac、Linux 或 Windows 环境中运行。按照说明进行操作,例如 https://docs.pivotal .io/pcf-dev/install-windows.html 对于 Windows,让 PCF Dev 在您的计算机上运行。这基本上分为三个步骤:

  • Getting Virtual Box
  • CF command line interface
  • Finally, the PCF Dev
Starting PCF Dev

我们第一次开始使用cf dev start,需要很长时间才能下载VM镜像(4 GB),解压(20 GB) ),然后启动PCF的各种服务。因此,一旦 VM 被下载并运行,我们只需在 Cloud Foundry 服务运行的情况下暂停和恢复 VM。

启动 PCF Dev 的命令行选项如下:

  1. Assuming you have a multi-core machine, you can allocate half the cores for this VM, such as -c 2 for a four core machine.
  2. The SCS version will use 8 GB of memory; to keep the buffer, let's use 10 GB of memory which is expressed in terms of MB on the command line.
  3. We will need the services of MySQL and SCS for the next chapter. Internally, SCS needs RabbitMQ to run. Hence, let's include all servers while running the instance.
  4. It is optional to give the domain and IP address, and hence, we will skip -d and -i options.
  5. Set the environment variable PCFDEV_HOME to a specific folder on a drive that has a good amount of space, so that it does not default to the home folder on the home drive. We would recommend the home folder to be a fast drive like SSD, as the Cloud Foundry start and stop operations are very I/O intensive.

所以,我们的启动命令如下:

cf dev start -c 2 -s all -m 10000  

这将需要很长时间才能最终准备好 PCF 开发环境。

加快开发时间

每次启动整个 PCF Dev 环境时,很难等待 20 分钟。完成一天的工作后或在关闭笔记本电脑之前,您可以暂停 PCF Dev by 使用 cf dev suspend 并在第二天使用 cf dev resume 命令恢复。

其他有用的命令包括:

  • A default PCF Dev creates two users—admin and user. To install or manage the applications, you should login as one of the users. The command cf dev target logs you in as a default user.
  • The cf dev trust command installs a certificate to enable SSL communication, so that you don't need to use parameter -skip ssl every time you log in on the command line or on an application manager in the browser.
  • The cf marketplace command (once you have logged in as a user) shows the various services that can be installed in the org and space.

让我们看看到目前为止讨论的命令的输出:

读书笔记《cloud-native-applications-in-java》云-本机应用程序运行时

正如我们在市场中看到的那样,由于我们以所有服务选项启动 PCF Dev,我们可以看到市场已经准备好使用七种服务。

Creating the MySQL service on PCF

从列表中,在本章中,我们将配置我们的 product 服务以使用 MySQL 数据库并查看 Spring Cloud 服务,例如断路器仪表板和其他服务下一章。

运行以下命令:

cf create-service p-mysql 512mb prod-db

检查服务是否正在运行:

读书笔记《cloud-native-applications-in-java》云-本机应用程序运行时

Running the product service on PCF Dev

让我们创建一个 product 服务的简化版本,它只连接到我们之前创建的用于运行查询的 MySQL 服务。

您可以编写第 3 章中的练习代码,设计您的云原生应用程序或从 Git 下载文件到您的 Eclipse 环境。值得注意的文物有:

  • In the Maven file:
    • Note that, in the following screenshot, we have renamed our artifact to pcf-product.
    • A new dependency worth noting is the spring-cloud-cloudfoundry-connector. This discovers the services bound to the Cloud Foundry application, such as MySQL configuration, and uses them.
    • We have included a MySQL connector for the JPA to connect to the MySQL database:
读书笔记《cloud-native-applications-in-java》云-本机应用程序运行时
  • In the application.properties file:
    • Notice that we have not given any MySQL connection properties, such as database, user, or password. These are picked up automatically by the Spring application, when the application is uploaded into Cloud Foundry and binds with the MySQL database service.
    • The auto create setting in case of MySQL should be true only for development purposes as it will recreate the database on every application deploy. In the UAT or production profile, this setting will be none:
management.security.enabled=false
logging.level.org.hibernate.tool.hbm2ddl=DEBUG 
logging.level.org.hibernate.SQL=DEBUG 
spring.jpa.hibernate.ddl-auto=create 
  • The ProductSpringApp class is simplified to a plain Spring Boot start up application. We will enhance this in the next chapter for metrics, lookup, load balancing, monitoring, and management:
读书笔记《cloud-native-applications-in-java》云-本机应用程序运行时
  • The ProductRepository class only has one method, called findByCatId, listed. The rest of the methods, such as get, save, delete, and update are automatically derived in the repository.
  • The ProductService, product, and other classes are unchanged from those in Chapter 3, Designing Your Cloud-Native Application.
  • In the manifest.yml file:
    • This is the new file containing instructions for deploying into cloud foundry
    • We will write the most basic version that has the application name, allotment of 1 GB of memory space, and the binding to the MySQL service from CloudFoundry
    • The random route lets the application take a route to reach the URL without having collisions in case of multiple versions:
读书笔记《cloud-native-applications-in-java》云-本机应用程序运行时

项目准备就绪后,运行 mvn install 以在 中创建综合的 .jar 文件目标目录。它的名称应该与 manifest.yml 文件中的 .jar 的名称相匹配。

Deploying to Cloud Foundry

部署到 Cloud Floundry 很简单,使用命令 cf push pcf-product,如下:

读书笔记《cloud-native-applications-in-java》云-本机应用程序运行时

Cloud Foundry 做了很多工作,在空间中创建应用程序,创建到达应用程序的路由,然后将各种服务与应用程序绑定。如果您对幕后发生的事情感兴趣,您或许应该阅读更多有关 Cloud Foundry 的内容。

部署完成后会看到success方法,如下:

读书笔记《cloud-native-applications-in-java》云-本机应用程序运行时

请注意在前面的屏幕截图中生成的 URL。

它是 http://pcf-product-undedicated-spirketting.local.pcfdev.io。我们将在下一章中看到如何使这个 URL 更短。

如果您在启动时遇到错误,例如配置错误或缺少几个步骤,您始终可以通过在命令行中输入以下命令来检查日志:

cf logs pcf-product --recent

现在,是时候测试我们的服务了。在浏览器窗口中,运行我们一般运行的两个服务:

  • http://pcf-product-undedicated-spirketting.local.pcfdev.io/product/1
  • http://pcf-product-undedicated-spirketting.local.pcfdev.io/products?id=1

您将看到来自数据库的响应,即输出和日志,如下所示:

读书笔记《cloud-native-applications-in-java》云-本机应用程序运行时

这完成了将我们简单的 product 服务部署到 PCF Dev 上的 PCF。

Summary


在本章中,我们看到了支持云原生应用程序的各种运行时组件,并在各种运行时(例如 Kubernetes 和 Cloud Foundry)上运行我们的应用程序。

在下一章中,我们将在 AWS 云上部署我们的服务。