四、PaaS應用實踐
1. 應用部署條件
-
APP的應用開發原則
應用必須遵從無狀態規則,只有遵從無狀態規則才能避免容器故障帶來的單點問題。
-
APP的應用部署yaml規範
Web應用:
Work應用:
Yaml規範:
-
容器內置環境變量(後續有例子)
$WEB_PORT、$APPID、$LOG_FILE, $INSTANCEID, $USER_DIR
2.如何部署應用
第一步:選擇應用類型、環境、實例配置等信息。
第二步:創建成功,默認生成一個應用。
第三步:利用web方式上傳應用zip包,應用描述yaml文件非常重要。
第四步:應用日誌相關配置。
日誌輸出位置要嚴格要求的,不能隨便自定義路徑,只能輸出到 /opt/logs目錄下,而且自定義的日誌文件是不會被採集和保存的,如果想要被PAAS平臺收集並保存必須寫到它們預定義的環境變量 ${LOG_FILE}中,提供一個log4j的配置片段,如下:
log4j.rootCategory=INFO,FILE
log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=[%d{yyyy-MM-dd HH\:mm\:ss}]%-5p %c(line\:%L) %x-%m%n
log4j.appender.FILE=org.apache.log4j.DailyRollingFileAppender
log4j.appender.FILE.Threshold = INFO
log4j.appender.FILE.File=${LOG_FILE}
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.FILE.layout.ConversionPattern=[%d{yyyy-MM-dd HH\:mm\:ss}]%-5p %c(line\:%L) %x-%m%n
第五步:除了提供日誌搜索,監控視圖和安全策略外,還提供SSH功能。
提供了爲每個實例單獨的開啓SSH管理功能,需要上傳了公鑰,然後開發者可以直接登陸,但僅有app權限,限定其存儲空間和可操作的命令。
根據提供的ssh命令,可以登錄到容器進行查看了。
3.如何使用服務
PAAS平臺還應提供的服務,mysql,memcache,redis,storage等基本服務都支持,滿足了應用的需求,僅以使用redis爲例介紹一下如何使用redis的緩存服務功能。
第一步:需要到服務中去申請一個redis服務,可以自定義服務名稱。
第二步:PAAS針對申請Redis服務提供一個URL可用的服務列表,然後也提供了獲取服務列表認證所需要的uid和password。
第三步:應用程序使用申請Redis服務時,建議使用提供的uid和password來動態獲取配置信息,這樣支持動態配置生效。
//獲取redis服務列表
static List<RedisInstanceNode> getNodes(String uid, String password) throws ServiceException {
Map<String, String> params = ParamUtils.getDefaultParams();
params.put("uid", uid);
params.put("password", password);
String endpoint = "http://internal.cloudscape.com";
String action = "/redis/service_instance/nodes";
String url = endpoint + action;
int timeout = HttpUtils.getRestTimeout();
if (httpService == null) {
httpService = new HttpServiceImpl();
}
HttpService.HttpResult result = httpService.httpGet(url, params, timeout);
String info = result.getResult();
Map<String, JsonNode> res = JsonUtils.readValueAsJson(info);
JsonNode nodesJson = res.get(ApiKeys._nodes);
if (nodesJson == null || nodesJson.isNull()) {
log.info("open api return error message, appinfos is empty , code: " + result.getCode() + ", message: "
+ res.get(ApiKeys._message));
return Collections.emptyList();
}
List<RedisInstanceNode> list = (List<RedisInstanceNode>) JsonUtils.readValueAsList(
JsonUtils.writeValueAsString(nodesJson), ArrayList.class, RedisInstanceNode.class);
return list;
//根據返回的實例nodes列表構建redis 連接池。
private static ShardedJedisPool pool;
for (RedisInstanceNode redis : nodes) {
String ip = redis.getIp();
int port = redis.getPort();
int master = redis.getIsMaster();
JedisShardInfo jsi;
if (master == 1) {
jsi = new JedisShardInfo(ip, port, "master");
jsi.setPassword(key);
jsi.setTimeout(3600000);
shards.add(jsi);
} else {
continue;
}
}
JedisPoolConfig jpc = new JedisPoolConfig();
jpc.setMaxActive(500);// 最大活動實例數目
jpc.setMaxIdle(200);// 最大停止實例數目
jpc.setMaxWait(5000);// 最大等待時間
jpc.setTestOnBorrow(false);
pool = new ShardedJedisPool(jpc, shards);
//使用連接池,進行數據set與get
try {
jedis = pool.getResource();
jedis.setex("test-key", defaultTimeout, "test-value");
} catch (Exception ex) {
log.error(ex.getMessage(), ex);
if (jedis != null) {
pool.returnBrokenResource(jedis);
}
} finally {
if (jedis != null) {
pool.returnResource(jedis);
}
}
其他幾個服務類似,最關鍵針對不同的服務要具有分佈式的特性,就是針對不同開源服務組件進行二次開發,以服務插件方式集成到平臺上,提供不同應用使用。同時,要考慮組件監控與報警機制,爲應用開發者提供一站式平臺。
五、PaaS其他功能
1.實例配置
應用可以根據業務評估所需資源,支持最小最大動態實例配置 ,支持根據規則引擎動態自動縮擴容。
2.綁定域名
應用不僅僅提供默認域名,還可以綁定業務自有域名。
3.綁定服務
應用可以申請依賴中間件服務,並設置配額和權限。
4.粘性會話
應用可以開啓粘性會話,儘可能保持用戶訪問狀態,但若存在實例調度,會影響部分用戶狀態有效性。完美方案,建議採用分佈式緩存來保持有效性。
5.應用監控
圍繞Node、Container和App三個維度的指標分析爲應用提供可視化展示。
6.應用日誌
基於ES搭建了一套搜索應用日誌的功能。
7.應用安全
對於應用層提供UA阻斷、IP名單、流量限制;
對於網絡層, 爲應用採用ovs+floodlight控制容器與服務的隔離。
8.應用授權
提供了應用授權給非管理員之外角色也擁有管理APP能力。