首页 > 技术文章 > 浅谈搜狐云景PAAS平台

claireyuancy 2017-05-21 21:08 原文

前言:

        搜狐云景作为搜狐的paas平台,在2014年5月22日的云计算大会上正式公布了公測。初測,注冊用户必须先申请邀请码參与公測会赠送用户100元电子券,经过实名认证之后会再赠送100电子券。目測能够对试用用户基本app够跑半年。

        除了用户中心的一些基本安全信息设置和各种账单外。我想主要对其控制台的使用进行研究一番。

废话不多说,在绑定邮箱并充值10元成正式用户之后,无阻挡进行各种測试吧。

dashboard非常清新干净,是一个对用户基本消费情况和使用资源服务的基本概览。


---------------------------------------------------


一、来创建个应用

        这里须要选择选择应用的基本类型是web或后台worker;

        执行环境须要事先选择好,其java就提供三种不同的执行环境,支持语言类型也挺多的,主要的主流语言都有支持到了。

        实例类型也就是容器类型,使用linux lxc技术,提供了六种不同的容器来执行我们的程序。


创建成功之后,会有一些默认的配置。

域名:cstest.sohuapps.com
版本号:1
实例配置:3-8。能够自己定义配置
容器类型:C2。能够自己定义配置
黏性会话:关闭。能够自己定义配置
外网訪问:关闭,能够自己定义配置
git服务:git@git.cloudscape.sohu.com:cs/cstest.git,据了解兴许会开启git push自己主动部署功能。

自己主动调度:开启,能够自己定义规则引擎,这个比較牛逼,目測国内paas还没有支持到这点的。</span>


笔者发现,

假设我们没有上传程序包,它会依据我们创建应用选择的执行环境提供一个默认的程序包放到应用的版本号1中。

启动之后。訪问域名 http://cstest.sohuapps.com 就能看到一个非常easy的hello world!


--------------------------------------------------

二、具体解释代码包

经过比較深入的了解,代码包结构首先不管哪种语言都仅仅能是zip包的结构,解开之后的标准文件夹例如以下:



不难发现。有这样几个文件或者文件夹:

app.yaml 文件。
承载整个app执行的核心配置文件
app 项目执行的核心代码文件夹
页面代码文件夹,对于Java,是WEB-INF所在的文件夹。
对于PHP, 是PHP页面所在文件夹。
conf 个性化配置文件夹。
包含,nginx server段自己定义配置、nginx server段自己定义配置、自己定义host配置等
bin 用户自己定义脚本目


然后。我要重点剖析一下这个app.yaml文件,它的配置有无、是否正确、详细參数设置直接决定app的 执行状况和监控状态。

对于搜狐云景paas上提供的八种执行环境。它们的app.yaml配置都是不一样的,甚至 于python与python on webpy的app.yaml配置都是不一样的。

以下我对于云景提供的六种语言,八类环境的配置进行具体介绍,并为每一个执行环境提供一个可执行的模板程序包,为大家提供參考。


2.0 所有參数

首先贴上一张提供的全部參数配置。但并非每一个执行的语言都能使用



2.1 Java on jetty


appid: 666666666
start: $JETTY_START
tcp_health: false
tcp_health_port: [8001, 8002]
try_restart: {fall: 10, enable: true}
web_health: true
web_health_conf:
    path: /
    success: [200, 201, 403, 301, 302]
    timeout: 500ms
[代码演示样例]

2.2 Java on resin

appid: 666666666
start: $RESIN_START
tcp_health: false
tcp_health_port: [8001, 8002]
try_restart: {fall: 10, enable: true}
web_health: true
web_health_conf:
    path: /
    success: [200, 201, 403, 301, 302]
    timeout: 500ms
[代码演示样例]

2.3 Java on tomcat

appid: 666666666
start: $TOMCAT_START
tcp_health: false
tcp_health_port: [8001, 8002]
try_restart: {fall: 10, enable: true}
web_health: true
web_health_conf:
    path: /
    success: [200, 201, 403, 301, 302]
    timeout: 500ms

[代码演示样例]

2.4 PHP

appid: 666666666
start: $PHP_FPM_START

[代码演示样例]

2.5 LUA

appid: 666666666
start: $LUA_START
[代码演示样例]

2.6 NODEJS

appid: 666666666
web_health: true
web_health_conf: 
    path: /
    timeout: 500ms
    success: [200,201,403,301,302]
try_restart: 
    enable: true
    fall: 10
start: $NODEJS $USER_DIR/app/main.js

[代码演示样例]

2.7 PYTHON

appid: 666666666
start: $UWSGI_START
[代码演示样例]

2.8 PYTHON with WEBPY

appid: 666666666
start: $PYTHON $USER_DIR/bin/main.py 8080
try_restart: {fall: 10, enable: true}
web_health: true
web_health_conf:
    path: /
    success: [200, 201, 403, 301, 302]
    timeout: 500ms


2.9 RUBY ON RAILS

appid: 666666666
web_health: true
start: /opt/apps/ruby/bin/unicorn_rails -c /opt/src/app/unicorn.rb -D
stop: kill $(cat /opt/conf/unicorn.pid)

[代码演示样例]

总结一下。

appid是貌似9位随机数字。start是其依据配置命令启动的參数,这俩參数是必须滴。
从其app.yaml的配置来看。其格式要求是非常严格的,必须严格依照 yaml的格式填写。包含空格,缩进等方面,比这就在这方面吃过亏。
其次,从其每种执行环境的配置来看,各项參数并非在每一个执行环境和语言中都能支持到的。须要做些调整,笔者最大化的使用了这些參数。
最后。要使用演示样例代码仅仅须要。改动zip包中app.yaml中的appid为你的appid就可以。
---------------------------------------------------------------------

三、高级进阶

提供语言支持太多。不能面面俱到,以下以java为例,介绍一下搜狐云景提供的一些高级功能。

3.1 日志输出

        搜狐云景对日志输出位置要严格要求的。不能随便自己定义路径。仅仅能输出到 /opt/logs文件夹下,并且自己定义的日志文件是不会被採集和保存的,假设想要被云景paas收集并保存必须写到它们提前定义的环境变量 ${LOG_FILE}中。
        因为笔者使用log4j作为日志输出,因此,给大家提供一个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

哈。是不是非常easy呢。

可是,要知道假设要使用log4j的配置,还须要做一些特定的配置,比方须要配置一个servlet来载入logj.properties文件,不多说。自行搜索。笔者后面也会附上代码包供各位看官细细研究。

使用的方式不外乎例如以下:
Logger log = LoggerFactory.getLogger(LogTest.class);

log.info("info| " + Thread.currentThread().getName() + " is running!");
log.warn("warn| there is some warning messages");
log.debug("debug| I am doing system debug");
log.error("error| sorry ,some errors happend!");
log.trace("trace| unknown messages following!");


3.2 服务使用

        纵观搜狐云景提供的服务,mysql,memcache,redis,storage等基本服务都支持,满足了我的大部分需求,笔者仅以使用redis为例介绍一下怎样高大上的使用redis的缓存服务功能。
首先须要到服务中去申请一个redis服务,记住是能够自己定义服务名称的哦。

        

然后笔者详细介绍一下代码中的使用方案。
        它们会提供一个URL告诉我们可用的服务列表,然后也提供了获取服务列表认证所须要的UID和password。

笔者建议使用提供的uid和password来在自己的程序中动态获取。http rest的get请求方式。你懂得。
        贴上两段代码。来获取redis实例。并构建使用它。

//(a)、获取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.sohu.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;
	}
//<span style="font-family: Arial, Helvetica, sans-serif;">(b)、</span><span style="font-family: Arial, Helvetica, sans-serif;">依据返回的实例nodes列表构建redis 连接池,笔者使用了强大的jedis。

</span>

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);
//(c)、使用连接池,进行数据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);
			}
		}
好了,这样就能使用redis服务了,其余的几类服务类似吧。


3.3 ssh登录

首先说。这个功能必须赞一个。敢于把ssh功能开放出来。是一个非常大的勇气。

上个图,


能够看到能够为每一个实例单独的开启SSH管理功能。这就相当于是个VPS拉。前提是要上传了公钥之后才干使用这么强大的功能。
依据提供的ssh命令。能够登录到容器进行查看了。

      

只是。别失望。非常多命令是不能使用的哦。看来是对命令进行了精简呢。

只是这已经是非常强大了。进去能看到我们的自己的日志了和进程等信息。

期待未来有更好更强大的功能。


尽管有这么多优点,可是还是有一些不足要吐一吐的。
 
  • 1、非常抱歉。ssh的管理功能不能每一个实例都能打开,最多仅仅能起两个,好在能够关闭。自己能自由切换。
  • 2、然后,其停止和卸载app的地方隐藏的非常深啊。类似于github上的要delete一个项目一样。要深层隐藏,可能为了确保用户不误操作吧。
  • 3、配置app.yaml比較麻烦,有个模板相应改是好点的。

  • 4、服务开放的尽管主要的够用,可是还是少了点,像非常多cdn呐,mongodb啊,存储类的服务都没有,期待非常快开放。

email:pautcher@gmail.com

微博:http://weibo.com/pautcher

未完,待续......

以上内容,纯属笔者千辛万苦呕心沥血书写,如有雷同。纯属不幸。


微博:http://weibo.com/pautcher

推荐阅读