• Java 运行环境:重装上阵

    reloaded

    年初的时候我们推出了基于容器的 Java 运行环境,经过半年时间的不断改进和优化,容器运行环境已经非常的稳定,在易用性上也有了长足的进步,所以我们决定,从下周起:

    • 容器 Java 运行环境将成为 Java 应用默认也是唯一可选的运行环境。
    • 下线旧 Java 运行环境(关闭创建入口,已经创建应用的用户和企业用户可以继续使用)。

    下面,就让我们看看容器 Java 环境都有哪些特性和功能:

    原生环境

    基于 Docker 容器,采用 Tomcat8 作为 Web 服务器,OpenJDK1.8 作为运行环境,应用不用修改一行代码即可直接部署到云端,100% 成功的部署率。

    Eclipse 插件极速部署

    对于容器 Java 应用,除了提供传统的 Git 部署和网页上传的方式以外,我们还提供了 Eclipse 插件,让您不用登录新浪云控制台就可以一键部署应用,加速您的应用的整个开发和调试流程。

    内置对分布式 Session 的支持

    容器 Java 环境已经内置了对分布式 HttpSession 的支持,只需要简单的几个配置,就可以让您的应用获得一个稳定、可靠、安全的分布式 Session 解决方案。

    Web 终端

    让您可以从网页中直接登录 JVM 运行的服务器,查看 JVM 的运行状态。

    共享存储

    应用可以通过挂载,将对应的共享存储卷映射进容器中,使应用获得本地文件读写和数据持久化功能。

    更多功能、特性和服务使用文档请参见: https://www.sinacloud.com/doc/sae/java.html

  • 如何在新浪云上部署一个 socket.io 应用

    socket.io

    Socket.IO aims to make realtime apps possible in every browser and mobile device, blurring the differences between the different transport mechanisms. It's care-free realtime 100% in JavaScript.

    socket.io 是一个为实时应用提供跨平台实时通信的库。socket.io 旨在使实时应用在每个浏览器和移动设备上成为可能,模糊不同的传输机制之间的差异。socket.io 在新浪云也有着广泛的使用,比如容器应用中的 Web 终端、Redis 服务的管理页面都是基于 socket.io 来实现的。

    下面我们以 socket.io 官方的 聊天室示例 为例,详细说明一下一个 socket.io 应用在新浪云上的部署过程。

    如何部署

    首先,在新浪云『SAE 控制台』中选择『创建新应用』,运行环境选择 容器 ,实例数目选择 1 (注意,这里容器的实例数目必须为 1 ,多实例需要额外配置,下文会有详细说明)。

    下载 sinacloud/nodejs-getting-started 这里的代码,切换到 socket.io 分支,该分支下为 socket.io 聊天室代码的一个 clone。

    添加一个名叫 sinacloud 的远程 Git 仓库,仓库的地址可以在『应用 / 代码管理』页面看到,并将本地的 socket.io 分支的代码推送到远程的 master 分支。

    $ git clone https://github.com/sinacloud/nodejs-getting-started.git
    $ cd nodejs-getting-started
    $ git checkout socket.io
    $ git remote add sinacloud https://git.sinacloud.com/<应用名>
    $ git push sinacloud socket.io:master
    

    完成,打开浏览器,输入应用的 URL,就可以访问刚才部署的聊天室应用了。

    多实例部署

    如果你的应用的访问量比较大,单容器实例已经满足不了需求需要多实例部署时,你还需要一些额外的配置。

    首先,您需要开启粘滞会话(Sticky Session),保证同一个会话的请求被转发给固定的后端。

    This is due to certain transports like XHR Polling or JSONP Polling relying on firing several requests during the lifetime of the “socket”.

    然后,创建一个 Redis ,并在『应用/环境变量』中将 Redis 的链接字符串加入到应用的环境变量中,变量名为 REDIS_URL

    修改代码,添加一个 socket.io-redis 的 adapter 用来在实例和实例之间通信。

    package.json

    "dependencies": {
        "express": "3.4.8",
        "socket.io": "^1.3.7",
        "socket.io-redis": "git://github.com/socketio/socket.io-redis#708de4cb7e42107084f51dd37f3060d7899b3fdd"
    }
    

    注意,这里使用的 socket.io-redis 是 github 上的 dev master 版本,npm 源里的版本不支持连接带认证的 Redis。

    var redis = require('socket.io-redis');
    // io 是创建的 socket.io 实例。
    // REDIS_URL 环境变量为刚才创建的 Redis 实例的链接字符串。
    io.adapter(redis(process.env.REDIS_URL));
    

    最后重新部署一下应用,现在你可以扩展(scale up)你的应用到任意个实例了。

    在 Redis 的管理页面里执行一下 monitor 命令,可以看到 socket.io-redis 用 Redis 的 PubSub 来实现实例和实例间的通信。

    redis:router> monitor
    OK
    1470280172.479693 [0 10.67.15.63:27857] "AUTH" "MfMfJdV2mat34FtaKnfi6IUeJt8aM7TZRgwnFpipLUTe6LnnryzAJkkOdIdetVdZ"
    1470280172.479911 [0 10.67.15.63:27857] "INFO"
    1470280186.825333 [0 10.13.144.213:47768] "AUTH" "MfMfJdV2mat34FtaKnfi6IUeJt8aM7TZRgwnFpipLUTe6LnnryzAJkkOdIdetVdZ"
    1470280186.827128 [0 10.13.144.213:47768] "PING"
    1470280193.949041 [0 10.67.21.62:51848] "subscribe" "socket.io#/#/#TJn0nk17WcnEB892AAAD#"
    1470280196.224730 [0 10.67.21.62:51849] "publish" "socket.io#/#" "\x93\xa6kKgr7Z\x83\xa4type\x02\xa4data\x92\xabuser joined\x82\xa8user
    name\xa2hi\xa8numUsers\x01\xa3nsp\xa1/\x83\xa6except\x91\xb6/#TJn0nk17WcnEB892AAAD\xa5rooms\xc4\xa5flags\x81\xa9broadcast\xc3"
    

    完整代码:https://github.com/sinacloud/nodejs-getting-started/tree/socket.io

    参考:

  • Elasticsearch服务正式公测

    es

    Elasticsearch是一款基于Lucene构建的开源分布式检索和分析引擎,通过RESTful API提供近实时的索引、搜索功能。

    新浪云Elasticsearch服务是基于开源的Elasticsearch 2.1版本搭建的一个集群,运行在新浪云高可用的分布式内网环境。对外开放HTTPS API,通过Basic Authentication使用。

    在新浪云上,您完全不需要管理Elasticsearch集群,只需要创建自己的索引就可以通过API索引、搜索数据,免去一切Elasticsearch的运维烦恼!

    详细请参见:https://www.sinacloud.com/doc/sae/services/es.html

  • 容器 Java 应用支持使用 Eclipse 插件一键部署

    最近,不少用户通过工单反馈容器运行环境部署 Java 应用的方法比较麻烦(使用 Maven,通过 Git 提交,线上编译发布),对于一些依赖比较多,尤其是一些多重框架组合使用的应用,整个部署过程非常的长,希望能够提供直接通过 War 包部署的功能。

    经过的一段时间的开发和测试,今天我们正式对外发布了 新浪云 Eclipse 插件 ,让你可以在 Eclipse 中一键将项目打成 War 包并部署到新浪云线上。 官方文档

    这里提供一个简单的示例给大家参考下:

    首先,我们下载并安装下 新浪云 Eclipse 插件 ,并在新浪云上创建一个自己的 容器 应用。

    打开 Eclipse ,创建一个新的 Web 应用(这里我创建了一个名为 test 的 Web 应用)。

    create-webapp

    创建一个 index.jsp 的页面,大致如下。

    create-page

    最后,在 test 项目上右键,选择 Sinacloud Web Services 菜单的第一个选项 Deploy,然后弹出如下对话框:

    deploy-app

    输入你的安全邮箱和密码,点击 OK 部署,稍等片刻,即可再浏览器中访问刚才部署的应用了。

    注:这里环境默认是 jdk1.8+tomcat8。

  • 一个 SNI 导致的外网访问 502 问题的解决过程

    最近有开发者通过工单系统向我们反馈 HTTPS 外网访问返回 502,而他本地访问是好的。通常这种情况一般是对端限制了我们的出口 IP。

    首先,我们在出口服务器上使用 curl 工具访问一下这个 URL,看下是否被对端限制了我们的访问。

    $ curl -v 'https://aa.com/'
    * About to connect() to aa.com port 443 (#0)
    *   Trying 104.24.1.1... connected
    * Connected to aa.com (104.24.1.1) port 443 (#0)
    * Initializing NSS with certpath: sql:/etc/pki/nssdb
    *   CAfile: /etc/pki/tls/certs/ca-bundle.crt
      CApath: none
    * NSS error -12286
    * Closing connection #0
    * SSL connect error
    curl: (35) SSL connect error
    

    通过 curl 的结果来看,显示已经建立了 TCP 连接,在 SSL Handshake 的时候失败。并不是对端限制了我们的出口 IP。

    在新浪云上外网 HTTP 访问是通过我们的一个叫做 FetchURL 的服务来实现的。看下 FetchuURL 的日志,同样也是 SSL Handshake 时发生了问题,同时我们可以更清晰的看到是在 get server hello 的时候出错的。

    SSL_do_handshake() failed (SSL: error:14077438:SSL routines:SSL23_GET_SERVER_HELLO:tlsv1 alert internal error)
    

    GET_SERVER_HELLO 是什么意思?我们来看下 SSL/TLS 握手。

    tls-handshake

    TLS 握手时,Client 先发出请求 ClientHello 把支持的 TLS 版本、加密算法等发送到 Server。Server 确认应答 ServerHello 确认要使用的 TLS 版本以及加密算法,如果 Client 没有匹配的 TLS 版本和加密算法,Server 就关闭加密通信。了解了 TLS 握手协议后再看这个错误 SSL23_GET_SERVER_HELLO:tlsv1 alert internal error 就好解释了。

    为了验证是不是 Client 不支持服务端的 TLS 版本和加密协议,我们使用 curl 指定一个比较强的加密协议: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256

    $ curl --ciphers ECDHE_ECDSA_AES_128_SHA -v 'https://aa.com'
    * About to connect() to aa.com port 443 (#0)
    *   Trying 104.24.113.140... connected
    * Connected to aa.com (104.24.113.140) port 443 (#0)
    * Initializing NSS with certpath: sql:/etc/pki/nssdb
    *   CAfile: /etc/pki/tls/certs/ca-bundle.crt
      CApath: none
    * SSL connection using TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
    * Server certificate:
    *   subject: CN=sni161691.aaa.com,OU=PositiveSSL Multi-Domain,OU=Domain Control Validated
    *   start date: May 24 00:00:00 2016 GMT
    *   expire date: Nov 27 23:59:59 2016 GMT
    *   common name: sni161691.aa.com
    *   issuer: CN=COMODO ECC Domain Validation Secure Server CA 2,O=COMODO CA Limited,L=Salford,ST=Greater Manchester,C=GB
    > GET / HTTP/1.1
    > User-Agent: curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.19.1 Basic ECC zlib/1.2.3 libidn/1.18 libssh2/1.4.2
    > Host: aa.com
    > Accept: */*
    

    成功!

    通过修改并重新编译 FetchuURL 添加 TLS 版本和椭圆曲线公共密钥 (ECC) 加密算法。部署到测试环境后,抓该 URL 却依然返回 502。看了下错误日志还报 SSL_do_handshake() failed 。结合错误日志我们再理一下 FetchuURL 的逻辑,FetchuURL 是解析了域名后直接访问 IP:PORT。dig 了一下这个域名,解析后的 IP 也是正确的。在我本机通过 IP:PORT curl 的时候,发现有这么个警告 using IP address, SNI is being disabled by the OS 。看了下该网站是部署在了一个云计算平台上,可能用到了 SNI 支持多域名虚拟主机的 SSL/TLS 认证。因为我们就是这么搞的,在 ClientHello 阶段把 Host 带到 Server,Server 再加载对应 Host 的证书在 ServerHello 阶段把证书和公钥等信息发给 Client。

    最后通过修改 FetchuURL 在 ClientHello 同时发送 Host,编译后部署到测试环境,这一次成功了。

subscribe via RSS