PAAS的架构设计与应用实践(二)

本文详细介绍了PaaS平台的应用实践,包括遵循无状态原则的应用部署、应用部署步骤、日志管理和服务使用,如Redis缓存服务的接入。此外,还提到了PaaS的其他功能,如实例配置、域名绑定、服务绑定、粘性会话、应用监控、日志管理和应用安全等。

四、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); 

//使用连接池,进行数据setget

 

                     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能力。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值