當前位置:
首頁 > 最新 > 六種開發環境部署大全:基於Openshift

六種開發環境部署大全:基於Openshift

前言

本文包含在Openshift上部署六種開發環境的步驟,分別是:

OpenShift for Fuse DevelopersEclipse Vert.x developmentSpring Boot developmentWildFly Swarm developmentNode.js developmentJava EE Batch Processing with OpenShift, WildFly

文中實驗源自:https://learn.openshift.com/middleware/,本文內容僅供參考。

第一種:部署Wildfly Swarm

Jave EE的應用通常被創建成ear或者war包。ear或者war包含應用和應用的所有依賴包,並被部署到應用伺服器上。多個Java EE的應用可以被部署到一個應用伺服器上。

而WildFly Swarm提供新的打包和運行 Java EE 應用的方式:直接在JVM桑通過 java -jar來運行Java應用。

WildFly Swarm基於WildFly,它是Jave EE標準的一個子集,因此它大大簡化了Jave EE應用實現微服務的複雜度。

在本實驗中,我們將在OCP上部署Wildfly Swarm。

首先先看一個Maven項目:

$ tree

├── pom.xml

└── src

└── main

├── fabric8

│ └── deployment.yml

├── java

│ └── com

│ └── example

│ ├── ApplicationConfig.java

│ ├── Greeting.java

│ └── GreetingResource.java

└── webapp

└── index.html

7 directories, 6 files

項目中:

pom.xml文件描述了如何構建這個項目。

ApplicationConfig.java:應用對外提供服務,接受外部請求。Greeting.java:描述了一個Java對象,它包含一個發送的問候信息。

GreetingResource.java:定義了/greeting and /stop RESTful 的endpoints.

接下來,用maven編譯並運行這個應用:

mvn wildfly-swarm:run

然後通過瀏覽器訪問這個應用進行測試:

接下來,在OCP中部署這個應用:

通過maven觸發fabric工具,在OCP中通過S2I部署這個應用:

mvn clean fabic8:deploy -Popenshift

查看應用routes

通過瀏覽器訪問routes:

第二種:部署Node.js

Node.js是一個基於Chrome V8的JavaScript運行時。

接下來,我們通過實驗展示在OCP上部署Node.js的應用。

先看一個Node.js的源碼:

package.json:項目的元數據,包括名稱、版本、依賴等。

app.js:主應用邏輯

app-config.yml :用於觸發、OpenShift ConfigMap

index.html :Web應用的頁面

先安裝依賴:

然後啟動應用:

通過瀏覽器訪問應用:

接下來,在OCP中部署應用:

通過瀏覽器訪問應用的route:

還可以給應用增加Configure Map

增加完以後,訪問route:

第三種:部署Java EE批處理,WildFly & JBeret

批處理通常是非互動式、後台執行的。批處理通通常涉及大量的數據處理和密集計算。

JBeret項目實現JSR 352(Java平台的批處理應用程序)以及Java SE和Java EE環境中的其他高級批處理功能。 JBeret包含在WildFly和JBoss EAP中,提供企業批處理功能。

接下來,我們通過實驗來展示 。

基於 WildFly image, 通過S2I的方式部署 Java batch應用:

部署應用:

oc rollout status dc/intro-jberet

oc expose svc intro-jberet

然後通過瀏覽器訪問應用:

接下來,創建PostgreSQL 資料庫:

oc new-app postgresql-ephemeral --name postgresql --param POSTGRESQL_USER=jberet --param POSTGRESQL_PASSWORD=jberet

#oc rollout status dc/postgresql

本實驗的批處理任務默認在作業XML文件csv2db中定義,包含兩個步驟:

csv2db.step1:它執行特定的任務:初始化資料庫表MOVIES。

"jdbc:postgresql://#?:postgresql;/#?:sampledb;"/>

"#?:jberet;"/>

"#?:jberet;"/>

CREATE TABLE IF NOT EXISTS MOVIES (

rank INTEGER NOT NULL PRIMARY KEY,

tit VARCHAR(128),

grs NUMERIC(12, 3),

opn DATE);

DELETE FROM MOVIES"/>

csv2db.step2:塊類型的步驟,讀取、處理和寫入數據塊,並重複讀取過程寫入過程,直到輸入結束。

"https://raw.githubusercontent.com/jberet/jsr352/master/jberet-support/src/test/resources/movies-2012.csv"/>

"java.util.Map"/>

"rank,tit,grs,opn"/>

"ParseInt;

NotNull, StrMinMax(1, 100);

ParseDate("yyyy-MM-dd")"/>

"insert into MOVIES (rank,tit,grs,opn)

VALUES (?, ?, ?, ?)"/>

"rank,tit,grs,opn"/>

"Int,String,Double,Date"/>

"java.util.Map"/>

在csv2db作業中,使用jberet-support庫中的3個批處理工件來實現處理邏輯:

jdbcBatchlet:針對目標資料庫執行SQL語句。csvItemReader:從CSV輸入源讀取,一次一行。jdbcItemWriter:將塊中的累積數據寫入目標資料庫。

使用curl命令行工具來調用REST API來執行各種批處理操作。 JSON輸出使用python -m json.tool格式化。

啟動csv2db任務:

curl -s -X POST -H "Content-Type:application/json" "//intro-jberet-jberet-lab.2886795303-80-simba02.environments.katacoda.com/intro-jberet/api/jobs/csv2db/start" | python -m json.tool

查看任務執行情況:

curl -s //intro-jberet-jberet-lab.2886795303-80-simba02.environments.katacoda.com/intro-jberet/api/jobexecutions/1 | python -m json.tool

查看任務的所有執行步驟:

curl -s //intro-jberet-jberet-lab.2886795303-80-simba02.environments.katacoda.com/intro-jberet/api/jobexecutions/1/stepexecutions/ | python -m json.tool

查看第二個任務的執行結果:

curl -s //intro-jberet-jberet-lab.2886795303-80-simba02.environments.katacoda.com/intro-jberet/api/jobexecutions/1/stepexecutions/2 | python -m json.tool

登錄到資料庫的pod中,查看錶的內容:

第四種:部署JBoss Fuse開發環境

本實驗將展示基於OCP部署JBoss Fuse Integration Services(FIS)2.0。JBoss FIS 2.0是一個敏捷、輕量級、現代化的開發框架,用於構建和部署高度可擴展的模塊化API。它不僅提供了基於容器的開發實踐,還提供了微服務框架,如:斷路器,追蹤,路由,轉換,審計等等。

JBoss FIS有兩種運行方式:

1.作為一個獨立的Java應用程序(SpringBoot)

2.作為Apache Karaf(OSGi)的服務

FIS在Openshift上有三種部署方式:

1.通過docker image

2.本地構建,然後push到OCP,利用B2I完成後續的工作。

3.使用S2I的方式構建。

本實驗展示的內容是:在Fuse上部署一個基於Spring Boot的People Service應用,該應用對外提供Rest API,實現微服務架構。

接下來,我們看實驗過程:

根據模板創建應用:

這個模板定義了和build相關的地址鏈接和信息:

創建了如下資源:

接下來,手工觸發build:

查看構建過程:

build成功,push鏡像:

然後觸發dc,構建了應用:

接下來,我們查看JBoss Fuse Hawtio console,查看Route Diagram10個子模塊被調用的情況:

在cli發起查詢一個用戶信息請求

再次查看Route Diagram,查看上一步curl操作調用的模塊(數字1表示被調用一次):

再發起一次查詢:

查看Route Diagram,相關模塊調用次數增加了一次:

再次觸發查詢

查看Route Diagram,相關模塊調用次數增加了一次:

這次我們換一種查詢方式,查看用戶列表:

查看Route Diagram,有兩個新的模塊被調用(最右邊一列)

接下來,為用戶列表增加一個新的用戶:

查看Route Diagram,又有兩個新的模塊被調用:

第五種:部署Eclipse Vert.x開發環境

Eclipse Vert.x是一個輕量級的微服務框架。本實驗中,我們將在OCP中通過fabric工具部署vert.x應用。

我們先看一個Http Java應用的源碼:

package com.example;

public class HttpApplication extends AbstractVerticle {

static final String template = "Hello, %s!";

@Override

public void start() {

// TODO: Create a router object

// TODO: Add router for /api/greeting here

// TODO: Add a StaticHandler for accepting incoming requests

// TODO: Create the HTTP server listening on port 8080

System.out.println("THE HTTP APPLICATION HAS STARTED");

}

// TODO: Add method for greeting here

}

接下來,我們通過maven編譯並運行這個應用:

應用已經運行:

接下來,分別動態為源碼增加如下內容(增加路由信息),應用自動刷新,實現響應式編程:

Router router = Router.router(vertx);

router.get("/*").handler(StaticHandler.create());

vertx.createHttpServer().requestHandler(router::accept).

三次輸入觸發了三次重新編譯和重新部署:

接下來,通過瀏覽器訪問應用:

接下來,為源碼動態增加如下內容:

private void greeting(RoutingContext rc) {

String name = rc.request().getParam("name");

if (name == null) {

name= "World";

}

JsonObject response = new JsonObject()

.put("content", String.format(template,name));

rc.response()

.putHeader(CONTENT_TYPE, "application/json; charset=utf-8")

.end(response.encodePrettily());

}

再在源碼中增加一個route:router.get("/api/greeting").handler(this::greeting);

然後,再次訪問應用鏈接,這次在頁面中輸入template,會有相應的返回值:

接下來,我們在OCP中部署vert.x。

先在OCP中創建一個項目:

部署應用,下圖fabric8:deploy是個小工具,通過mvn觸發,實現vertx應用的整個S2I的過程:

接下來,查看應用的route並進行訪問:

第六種:部署Spring Boot

Spring是最受歡迎的Java框架之一,提供了Java EE編程模型的替代方案。本實驗中,我們將在OCP中部署一個Spring Boot應用:

我們先看一個maven project:

$ tree

.

├── pom.xml

└── src

├── main

│ ├── fabric8

│ │ ├── credentials-secret.yml

│ │ ├── deployment.yml

│ │ └── route.yml

│ ├── java

│ │ └── com

│ │ └── example

│ │ ├── Application.java

│ │ └── service

│ └── resources

│ ├── application-local.properties

│ ├── application-openshift.properties

│ └── static

│ └── index.html

└── test

└── java

└── com

└── example

13 directories, 8 files

fabric8下的內容,是和容器相關的內容;

java下的內容是源碼和相關內容;

resources下分別是應用的配置文件和openshit的配置文件;

我們看一下Java的源碼:

查看應用的pom.xml:

Copyright 2016-2017 Red Hat, Inc, and individual contributors.

Licensed under the Apache License, Version 2.0 (the "License");

you may not use this file except in compliance with the License.

You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software

distributed under the License is distributed on an "AS IS" BASIS,

WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

See the License for the specific language governing permissions and

limitations under the License.

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

4.0.0

com.example

fruits

15-SNAPSHOT

Simple Fruits Application

Spring Boot - CRUD Booster

9.4.1212

1.5.8.RELEASE

2.20

3.5.30

me.snowdrop

spring-boot-bom

$

pom

import

spring-boot-starter

spring-boot-starter-test

test

spring-boot-maven-plugin

$

local

exec

repackage

local

true

openshift

io.fabric8

fabric8-maven-plugin

$

fmp

resource

build

通過在pom.xml中增加如下內容,將 Tomcat增加到應用中:

接下來,編譯並運行應用:

mvn spring-boot:run

瀏覽器訪問應用的route,此時應用還沒有連接資料庫,因此沒有內容。

接下來,給應用增加 JPA (Hibernate) ,讓它可以訪問關係型資料庫。在pom.xml中增加。

接下來,在pom.xml增加一段in-memory內存的描述

接下來,創建一個java的源碼Fruit.java,定義Entity class以更新資料庫中的內容(一個資料庫表模型):

import javax.persistence.Entity;

import javax.persistence.GeneratedValue;

import javax.persistence.GenerationType;

import javax.persistence.Id;

@Entity

public class Fruit {

@Id

@GeneratedValue(strategy = GenerationType.IDENTITY)

private Integer id;

private String name;

public Fruit() {

}

public Fruit(String type) {

this.name = type;

}

public Integer getId() {

return id;

}

public void setId(Integer id) {

this.id = id;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

}

再創建一個FruitRepository.java,它定義了對資料庫操作服務。

public interface FruitRepository extends CrudRepository {

}

再定義可一個sql,用於向數據中插入數據:

insert into fruit (name) values ("Cherry");

insert into fruit (name) values ("Apple");

insert into fruit (name) values ("Banana");

最後書寫一個應用測試程序:

package com.example;

import java.util.Collections;

import org.junit.Before;

import org.junit.Test;

import static org.junit.Assert.assertFalse;

import static org.junit.Assert.assertTrue;

@RunWith(SpringRunner.class)

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)

public class ApplicationTest {

@Autowired

private FruitRepository fruitRepository;

@Before

public void beforeTest() {

}

@Test

public void testGetAll() {

assertTrue(fruitRepository.findAll().spliterator().getExactSizeIfKnown()==3);

}

@Test

public void getOne() {

assertTrue(fruitRepository.findOne(1)!=null);

}

@Test

public void updateAFruit() {

Fruit apple = fruitRepository.findOne(2);

assertTrue(apple!=null);

assertTrue(apple.getName().equals("Apple"));

apple.setName("Green Apple");

fruitRepository.save(apple);

assertTrue(fruitRepository.findOne(2).getName().equals("Green Apple"));

}

@Test

public void createAndDeleteAFruit() {

int orangeId = fruitRepository.save(new Fruit("Orange")).getId();

Fruit orange = fruitRepository.findOne(orangeId);

assertTrue(orange!=null);

fruitRepository.delete(orange);

assertTrue(fruitRepository.findOne(orangeId)==null);

}

@Test

public void getWrongId() {

assertTrue(fruitRepository.findOne(9999)==null);

}

}

接下來,運行並進行檢查:

mvn verify

接下來,創建應用對外的service:FruitController.java

import java.util.List;

import java.util.Objects;

import java.util.Spliterator;

import org.springframework.web.bind.annotation.DeleteMapping;

import org.springframework.web.bind.annotation.GetMapping;

import org.springframework.web.bind.annotation.PostMapping;

import org.springframework.web.bind.annotation.PutMapping;

import org.springframework.web.bind.annotation.RequestMapping;

@Controller

@RequestMapping(value = "/api/fruits")

public class FruitController {

private final FruitRepository repository;

@Autowired

public FruitController(FruitRepository repository) {

this.repository = repository;

}

@ResponseBody

@GetMapping(produces = MediaType.APPLICATION_JSON_VALUE)

public List getAll() {

return StreamSupport

.stream(repository.findAll().spliterator(), false)

.collect(Collectors.toList());

}

//TODO: Add additional service calls here

}

接下來,運行應用:

mvn spring-boot:run -DskipTests

運行成功以後,通過瀏覽器訪問應用,已經可以看到資料庫中的內容,並可以對它進行操作:

同樣,我們可以很方便地將這個應用部署到OCP中:

創建資料庫:

oc new-app -e POSTGRESQL_USER=luke -e POSTGRESQL_PASSWORD=secret -e POSTGRESQL_DATABASE=my_data openshift/postgresql-92-centos7 --name=my-database

在應用pom.xml定義對資料庫的訪問內容:

pom.xml增加對spring boot的健康檢查內容:

部署應用:

mvn packagefabric8:deploy -Popenshift -DskipTests

訪問route:

參考鏈接:https://learn.openshift.com

大衛分享:

魏新宇

"大衛分享"運營者、紅帽資深解決方案架構師

專註開源雲計算、容器及自動化運維在金融行業的推廣

擁有紅帽RHCE/RHCA、VMware VCP-DCV、VCP-DT、VCP-Network、VCP-Cloud、ITIL V3、Cobit5、C-STAR、AIX、HPUX等相關認證。


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 大衛分享 的精彩文章:

一個虛擬化客戶上雲的需求分析&架構設計-大衛的Azure學習筆記大全

TAG:大衛分享 |