# Java运行环境

# 运行环境说明

# 工作流程

Java运行环境是新浪云推出的本地可写的Java运行环境,通过上传war包触发自动构建逻辑,将提交的war包打包为docker镜像,然后由新浪云的容器管理引擎启动生成的镜像实例运行,实例可以水平扩展以支持大流量。

# 工作流程示意图

Java应用的代码部署及服务发现过程如下图所示:

Java运行环境示意图

# 支持的JDK版本

Java运行环境当前支持以下的JDK版本:

  • 1.8 (推荐)
  • 1.7

# Tomcat版本

当前Java环境使用的Tomcat版本为8.0.35

# 创建应用

  1. 登录云应用管理平台https://sae.sinacloud.com (opens new window),如果没有账号请先注册;

  2. 点击“+创建应用”进入应用的创建页面; 点击创建应用进入应用管理页面

  3. 开发语言选择“Java”;

  4. 选择JDK版本;

  5. 选择单实例的配置; 选择Java应用配置

  6. 选择实例个数,开发阶段可以选择1,可以随时调整;

  7. 输入应用的二级域名前缀,二级域名的组成规则请参考应用名,应用名称(应用的中文介绍); 输入应用名、应用描述等

  8. 点击“确认创建”完成创建。

说明

  • 每个实例中将会拥有相同的代码,每个实例的资源配额为创建时指定的单实例配置
  • 实例的个数可以随时修改;
  • 计费的规则为:单实例价格 * 实例总数 * 实例的运行时长,按分钟计费。

# 计费说明

# 计费规则

计费的规则为:单实例价格 * 实例总数 * 实例的运行时长,按分钟计费。

其中单实例的价格可以从价格中心 (opens new window)查询。

例如单实例的配置为标准型,单价为0.06元每实例每小时,开启的实例个数为2,则一天的价格为:

0.06 * 2 * 24 = 2.88

# 流量计费

当前Java应用的流量不计费。

# 代码部署

# 上传war包部署

请参考war包部署章节。

# 使用 Eclipse 插件部署 Java 应用

借助于新浪云 Eclipse 插件,你可以快速将本地的 Java 应用部署到线上。

# 安装

首先下载 新浪云Eclipse插件包 (opens new window)

打开 Eclipse,点击顶部的菜单『Help/Install New Software/Add』。

war包插件部署

选择对话框顶部『Work with』 后面的『Add』按钮,并点击『Archive』选择下载到本地的插件包。

选择插件

点击『Next』,Eclipse 将引导您完成剩余的安装步骤。

# 使用

在 Eclipse 相应的项目点击右键选择 『Sinacloud Web Services/Deploy』,在弹出的对话框的 App Name 中填写相应的容器的应用名, UserName 填写安全邮箱, PassWord 填写安全密码。

使用插件

点击 OK ,插件会自动将项目打成 War 包并上传到新浪云部署,部署完成后,你可以在应用的『容器管理』页面看到对应的服务端进程当前的运行状态,在运行状态变成 运行 后,即可在浏览器中访问您的应用了。

说明

eclipse插件是新浪云为了简化war包部署开发的插件,如果您不是使用eclipse,可以手工导出war包从管理平台上传,如何上传请参考上传war包部署

# Hello world

# 准备工作

  1. 创建应用,选择Java环境,如果没有创建应用,请参考创建应用章节说明;

  2. 编写代码,导出war包;

如果只是用于测试,也可以下载新浪云准备的war包: 点击下载helloworld.war

项目于的源码在Github可以获取https://github.com/sinacloud/java-example-helloworld-war (opens new window)

# 上传war包

请参考代码部署章节部署war包。

如果从在线管理平台上传war包,看到任务执行的状态为成功时说明部署已经完成: war包部署成功

部署完成后,从容器管理的页面可以看到容器已经成功启动:

war包部署成功后的容器状态

# 访问应用

部署完成后,通过应用的二级域名访问项目,就会输出hello world的页面,如下图所示:

war包部署成功后通过URL访问

# 查看容器中的目录结构

从容器管理页面点击终端进入web terminal页面:

进入web 终端

执行ps -ef可以看到java进程:

Java进程

/app目录下执行ls -al可以看到工作目录的文件结构:

[root@dockerjava2 /app]# ls -al
total 12
drwxr-xr-x    9 root     root           110 Sep 30 09:42 .
drwxr-xr-x   20 root     root           243 Sep 30 09:41 ..
-rw-------    1 root     root            60 Sep 30 10:14 .ash_history
drwxr-xr-x    3 root     root          4096 Jun 29 11:46 bin
drwxr-xr-x    3 root     root           198 Jun 29 13:21 conf
drwxr-xr-x    6 root     root            54 Jun 29 11:46 jre
drwxr-xr-x    2 root     root          4096 Jun 29 11:46 lib
drwxr-xr-x    2 root     root             6 Aug  2  2016 logs
drwxr-xr-x    4 root     root            48 Sep 30 09:41 webapps
drwxr-xr-x    3 root     root            22 Jun 29 11:46 work

war包在/app/webapps目录下,目录下有一个ROOT.war,这个文件是最后一次上传的war包,系统将其自动命名为ROOT.war,ROOT目录是ROOT.war自动展开的目录,其中包含了Java项目运行的所有文件:

[root@dockerjava2 /app/webapps]# ls -al
total 80
drwxr-xr-x    4 root     root            48 Sep 30 09:41 .
drwxr-xr-x    9 root     root           110 Sep 30 09:42 ..
drwxr-xr-x    4 root     root            54 Sep 30 09:41 ROOT
-rw-r--r--    1 root     root         74333 Jan  1  1970 ROOT.war

查看ROOT目录结构:

[root@dockerjava2 /app/webapps/ROOT]# ls -al
total 96
drwxr-xr-x    4 root     root            54 Sep 30 09:41 .
drwxr-xr-x    4 root     root            48 Sep 30 09:41 ..
drwxr-xr-x    2 root     root            44 Sep 30 09:41 META-INF
drwxr-xr-x    2 root     root            21 Sep 30 09:41 WEB-INF
-rw-r--r--    1 root     root         97578 Feb  1  2017 index.jsp

# 协议支持

应用支持http、https和websocket协议(ws、wss)。

# 端口映射

# 工作原理

应用的负载均衡(新浪云提供)监听80和443端口,然后将请求转发到容器中的5050端口(Java应用的tomcat已经默认启动在5050端口),示意图如下:

协议及端口示意

# 支持的端口

容器中可以启动多个端口,但是仅5050端口会映射到负载均衡上,其他的端口只能在本地访问(127.0.0.1地址)。可以从环境变量中获取支持的端口,环境变量的key为:

PORT 

获取支持的端口。

请注意

  • 如果使用HTTPS访问,在负载均衡到容器间会转变为HTTP协议,可以从HTTP的header头中判断是否有HTTP-X-PROTO头,如果这个header头的值为SSL表示本次请求为HTTPS访问;
  • 如上所述,HTTPS证书应该传到负载均衡处(从管理面板的域名绑定处上传),不应该放到容器中。

# 日志系统

# 容器日志分类

容器日志分类stdoutstderr分类,分别是标准输出和标准错误输出的捕获。

因为容器的磁盘空间有限,大量的写入可能会占满磁盘导致服务不可用,请从程序中配置日志输出路径,将日志写到stdoutstderr分类,其中:

  • /proc/1/fd/1stdout的绝对路径
  • /proc/1/fd/2stderr的绝对路径

# 查询容器stdout日志

  1. 进入应用的列表页面https://sae.sinacloud.com (opens new window)
  2. 点击操作处的管理进入应用的管理中心
  3. 左侧导航选择“日志及监控”,选择“日志中心”进入日志管理
  4. 选择“容器日志”的“stdout”分类 查询stdout分类日志

# 查询容器stderr日志

  1. 进入应用的列表页面https://sae.sinacloud.com (opens new window)
  2. 点击操作处的管理进入应用的管理中心
  3. 左侧导航选择“日志及监控”,选择“日志中心”进入日志管理
  4. 选择“容器日志”的“stderr”分类 查询stderr分类日志

# SSH登录

# 说明

Java应用支持通过在线SSH终端登录到容器中查看进程的状态和系统的信息。

# 如何登录

  1. 进入应用的列表页面https://sae.sinacloud.com (opens new window)
  2. 点击操作处的管理进入应用的管理中心
  3. 左侧导航选择“运行环境管理”,选择“容器管理”进入应用的容器列表页面
  4. 点击需要管理的容器示例的“操作”区域的“终端”即可进入web版本的终端 进入web terminal
  5. 输入Linux命令可以查询进程的状态、执行其他的操作 在web terminal执行ps -ef命令

# 文件系统

# 本地文件系统

实例在创建时将会分配5GB的本地磁盘,用于存放程序的代码和系统文件等,你可以从程序往本地写文件,但本地的文件不是持久化存储,在重启后文件会删除

警告

  • 如果你需要持久化存储文件,请不要将文件写到本地文件系统,可以通过以下几种方式存储文件:

# 挂载共享存储

共享存储服务是为容器云提供的分布式存储服务,利用多副本写入实现数据高可靠性,并提升读取性能,可以提供数十M/S的峰值读写性能。

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

通过共享存储,还可以在不同的容器之间共享数据,实现跨容器的数据共享和交互。

有关共享存储的更多介绍,请参考共享存储章节,请参考以下步骤挂载共享存储:

  1. 共享存储 (opens new window)管理面板创建一个共享存储;
  2. 云应用管理平台 (opens new window)应用列表页面点击“管理”进入应用的管理中心;
  3. 左侧导航选择“运行环境管理”,“容器管理”进入容器管理页面; 如何进入容器管理页面
  4. 点击“挂载管理”进入挂载管理页面; 进入磁盘挂载的页面
  5. 点击“+新增挂载”,存储的分类选择“共享存储”,从下拉列表选择刚刚创建的存储,输入一个挂载路径。 填写挂载的信息

    说明

    挂载路径是系统的绝对路径,如果你挂载的路径在本地文件系统已经存在,则挂载后本地的文件系统将被覆盖。

  6. 选择“立即重启容器”后挂载会立即生效,挂载完成后可以看到挂载的详情: 挂载详情

挂载完成后,从容器的实例中可以看到挂载的路径: 在容器中查看挂载的路径

共享存储中的文件支持FTP管理,详情请参考共享存储的FTP管理章节。

挂载完共享存储到本地的路径后,就可以在程序中将需要存储的文件写到挂载的路径下了。

# 挂载本地存储

本地存储服务是为容器云提供的本地问年间存储服务,可以和本地磁盘读写一样速度的磁盘。

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

有关共享存储的更多介绍,请参考本地存储章节,请参考以下步骤挂载本地存储:

  1. 本地存储 (opens new window)管理面板创建一个本地存储;
  2. 云应用管理平台 (opens new window)应用列表页面点击“管理”进入应用的管理中心;
  3. 左侧导航选择“运行环境管理”,“容器管理”进入容器管理页面; 如何进入容器管理页面
  4. 点击“挂载管理”进入挂载管理页面; 进入磁盘挂载的页面
  5. 点击“+新增挂载”,存储的分类选择“本地存储”,从下拉列表选择刚刚创建的存储,输入一个挂载路径。 填写挂载的信息

    说明

    挂载路径是系统的绝对路径,如果你挂载的路径在本地文件系统已经存在,则挂载后本地的文件系统将被覆盖。

  6. 选择“立即重启容器”后挂载会立即生效,挂载完成后可以看到挂载的详情: 挂载详情

挂载完成后,从容器的实例中可以看到挂载的路径: 在容器中查看挂载的路径

本地存储中的文件支持FTP管理,详情请参考本地存储的FTP管理章节。

挂载完地存储到本地的路径后,就可以在程序中将需要存储的文件写到挂载的路径了。

# 静态文件处理

# 挂载存储设备

如果希望将静态文件从war包中拆离开,可以通过以上的挂载共享存储挂载本地存储将存储设备挂载到tomcat的工作目录。

例如将共享存储挂载到/app/webapps/public目录下:

说明

public可以换为其他名称,例如static,这个目录是访问链接后的一级目录名称,例如为static时用http://xxxx.applinzi.com/static/XXXXX去访问static目录下的文件。

共享存储挂载到public目录

挂载后,从容器的终端里就可以看到这个目录:

挂载后从终端中看到的文件夹

文件下的目录为:

[root@dockerjava2 /app/webapps/public]# ls -al
total 25765
drwxrwxrwx    4 root     root          4096 Jun 28 11:04 .
drwxr-xr-x    4 root     root            48 Sep 30 09:41 ..
drwxrw-rw-    2 12345    12345         4096 Nov 21  2017 2222
drwxrw-rw-    2 12345    12345         4096 Nov 16  2017 333
-rw-rw-rw-    1 12345    12345      8791434 Nov 15  2017 IMG_4371.jpg
-rw-rw-rw-    1 12345    12345      8752173 Nov 15  2017 IMG_4372.jpg
-rw-rw-rw-    1 12345    12345      8819780 Nov 15  2017 IMG_4373.jpg
-rw-------    1 root     root          3386 Jun 28 11:04 logging.properties
-rw-rw-rw-    1 12345    12345         2402 Nov 21  2017 weibodm_service.class.php

和共享存储下的文件结构是一致的:

共享存储下的文件结构

输出一个hello world到index.txt中:

[root@dockerjava2 /app/webapps/public]# echo "hello world" > index.txt
[root@dockerjava2 /app/webapps/public]# ls
2222                       IMG_4373.jpg
333                        index.txt
IMG_4371.jpg               logging.properties
IMG_4372.jpg               weibodm_service.class.php

这是就可以用URL直接访问这个文件,http://你的应用名.applinzi.com/public/index.txt

通过URL访问静态文件

# 文件需要放到根目录下

如果需要临时在根目录下添加文件用于验证,可以在/app/webapps/ROOT目录下添加文件实现,例如在/app/webapps/ROOT目录下加一个index.txt文件:

[root@dockerjava2 /app/webapps/ROOT]# echo 'aa' > index.txt 
[root@dockerjava2 /app/webapps/ROOT]# ls -al
total 100
drwxr-xr-x    4 root     root            71 Sep 30 14:38 .
drwxr-xr-x    4 root     root            65 Sep 30 14:37 ..
drwxr-xr-x    2 root     root            44 Sep 30 09:41 META-INF
drwxr-xr-x    2 root     root            21 Sep 30 09:41 WEB-INF
-rw-r--r--    1 root     root         97578 Feb  1  2017 index.jsp
-rw-r--r--    1 root     root             3 Sep 30 16:48 index.txt

添加后就可以URL去访问根目录下的文件,例如:

访问根目录下的文件

请注意

  • 如果应用存在不止一个实例,则需要在每一个实例的终端下都执行添加文件操作,否则会出现数据不一致;
  • 临时添加的文件在重启后会丢失,如果需要永久保存,请把文件添加到war包中再部署。