首先确保 Eclipse 已经安装 Maven 插件,并将项目以 Maven Project 方式导入 Eclipse 中,在 Package Explorer 视图右键点击项目,选择 Run As > Run Configurations…,选择 Application,设置 Main class:(示例项目为 cn.leancloud.demo.todo.Application),将 Environment 标签页增加以下环境变量和相应的值:
名称
值
LEANCLOUD_APP_ENV
development
LEANCLOUD_APP_ID
{{appid}}
LEANCLOUD_APP_KEY
{{appkey}}
LEANCLOUD_APP_MASTER_KEY
{{masterkey}}
LEANCLOUD_APP_PORT
3000
然后点击 run 按钮启动应用。
接入 Web 框架
LeanEngine Java 依赖 Servlet 3.1.0,你可以使用任何基于 Servlet 3.1.0 的 Web 框架。
你需要先在这些平台上创建一个项目(如果已有代码,请不需要选择「Initialize this repository with a README」),在网站的个人设置中填写本地机器的 SSH 公钥(以 GitHub 为例,在 Settings > SSH and GPG keys 中点击 New SSH key),然后在项目目录执行:
网站托管开发指南 · Java
网站托管是云引擎的一个子模块,允许你用 Java 开发一个 Web 程序,提供云函数和 Hook,还可以提供静态文件的托管和自定义的路由、绑定你自己的域名。你可以用它为你的移动应用提供一个介绍和下载页、开发一个管理员控制台或完整的网站,或者运行一些必须在服务器端运行的自定义逻辑。
如果你还不知道如何创建云引擎项目,本地调试并部署到云端,可以先阅读一下 云引擎快速入门。其他相关文档包括:
这篇文档以 Java 为例,但云引擎还支持其他多种语言,你可以选择自己熟悉的技术栈进行开发:
从示例项目开始
我们为云引擎支持的各种语言准备了示例项目,建议从示例项目着手开始开发。
要理解如何从示例项目开始开发云引擎项目,本地调试,部署到云端,请先阅读 云引擎快速入门。
项目骨架
云引擎目前支持 Java 8、11、12、13、14 运行环境和 war 包运行,你的项目需要遵循一定格式才会被云引擎识别并运行。
云引擎 Java 运行环境使用 Maven 进行构建,所以 LeanEngine Java 项目必须有
$PROJECT_DIR/pom.xml
文件,该文件为整个项目的配置文件。构建完成后云引擎会尝试到$PROJECT_DIR/target
目录下寻找可以使用的包:java -jar <packageName>.jar
来运行。我们建议使用示例项目做为起步,因为一些细节的开发环境的配置会让开发调试方便很多:
java-war-getting-started
:使用 Servlet,集成 LeanEngine Java SDK 的一个简单项目,打包成 WAR 文件。spring-boot-getting-started
:使用 Spring Boot 作为项目框架,集成 LeanEngine Java SDK 的一个简单的项目,打包成 JAR 文件。Java 运行环境对内存的使用较多,所以建议:
云引擎运行 Java 应用时,会自动将
-Xmx
参数设置为实例规格的 70%,剩下的 30% 留给堆外内存和其他开销。如果你的应用比较特殊(比如大量使用堆外内存)可以自己定制-Xmx
参数。假设使用 2 GB 内存规格的实例运行,则可以在云引擎的设置页面增加「自定义环境变量」,名称为JAVA_OPTS
,值为-Xmx1500m
,这样会限制 JVM 堆最大为 1.5 GB,剩下 500 MB 留给持久代、堆外内存或者其他一些杂项使用。注意:-Xmx
参数如果设置得过小可能会导致大量 CPU 消耗在反复的的 GC 任务上。如果云引擎 实例规格 选择不当,可能造成应用启动时因为内存溢出(OOM)导致部署失败,或运行期内存溢出导致应用频繁重启。
Java 云引擎默认使用 Java 8 运行环境,如果希望使用其他版本的 Java,可以在项目根目录创建一个名为
system.properties
的文件,指定java.runtime.version
:注意,Spring Boot 模板项目目前只支持 Java 8,请勿在
system.properties
指定 Java 8 以外的版本。打包成 WAR 文件的项目
首先确认项目
pom.xml
中配置了 Jetty plugin,并且 web server 的端口通过环境变量LEANCLOUD_APP_PORT
获取,具体配置可以参考我们的 示例代码。然后使用 Maven 安装依赖并打包:
以下有几种方式可以本地启动:
命令行工具启动应用
更多有关命令行工具和本地调试的内容请参考 命令行工具使用指南。
提示:相对于其他启动方式,命令行工具有 多应用管理 功能,可以方便地切换不同应用环境。
命令行设置环境变量启动
通过以下命令将云引擎运行需要的环境变量设置到当前命令行环境中,并使用 jetty 插件启动应用:
提示:命令
lean env
可以输出当前应用所需环境变量的设置语句,外层的eval
是直接执行这些语句。 Windows 系统下需要手动设置lean env
输出的环境变量。使用 Eclipse 启动应用
首先确保 Eclipse 已经安装 Maven 插件,并将项目以 Maven Project 方式导入 Eclipse 中,在 Package Explorer 视图右键点击项目,选择 Run As > Maven build…,将 Main 标签页的 Goals 设置为
jetty:run
,将 Environment 标签页增加以下环境变量和相应的值:LEANCLOUD_APP_ENV
development
LEANCLOUD_APP_ID
{{appid}}
LEANCLOUD_APP_KEY
{{appkey}}
LEANCLOUD_APP_MASTER_KEY
{{masterkey}}
LEANCLOUD_APP_PORT
3000
然后点击 run 按钮启动应用。
打包成 JAR 文件的项目
使用 Maven 正常的安装依赖并打包:
以下有几种方式可以本地启动:
命令行设置环境变量启动
通过以下命令将云引擎运行需要的环境变量设置到当前命令行环境中,并启动应用:
提示:命令
lean env
可以输出当前应用所需环境变量的设置语句,外层的eval
是直接执行这些语句。 Windows 系统下需要手动设置lean env
输出的环境变量。使用 Eclipse 启动应用
首先确保 Eclipse 已经安装 Maven 插件,并将项目以 Maven Project 方式导入 Eclipse 中,在 Package Explorer 视图右键点击项目,选择 Run As > Run Configurations…,选择
Application
,设置Main class:
(示例项目为cn.leancloud.demo.todo.Application
),将 Environment 标签页增加以下环境变量和相应的值:LEANCLOUD_APP_ENV
development
LEANCLOUD_APP_ID
{{appid}}
LEANCLOUD_APP_KEY
{{appkey}}
LEANCLOUD_APP_MASTER_KEY
{{masterkey}}
LEANCLOUD_APP_PORT
3000
然后点击 run 按钮启动应用。
接入 Web 框架
LeanEngine Java 依赖 Servlet 3.1.0,你可以使用任何基于 Servlet 3.1.0 的 Web 框架。
使用数据存储服务
云引擎项目直接依赖于 Java Unified SDK 的 engine-core 模块,engine-core 又依赖于存储核心模块 storage-core。因此开发者可以直接使用 LeanCloud 的存储服务 来存储自己的数据。
如果使用项目框架作为基础开发,LeanEngine Java SDK 默认是配置好的,可以根据示例程序的方式直接使用。
如果是自定义项目,则需要自己配置:
配置依赖:在
pom.xml
中增加依赖配置来增加 LeanEngine Java SDK 的依赖:初始化:在正式使用数据存储之前,你需要使用自己的 App Key 进行初始化中间件:
健康监测
你的应用在启动时,云引擎的管理程序会每秒去检查你的应用是否启动成功,如果 30 秒 仍未启动成功,即认为启动失败;在之后应用正常运行的过程中,也会有定期的「健康监测」,以确保你的应用正常运行,如果健康监测失败,云引擎管理程序会自动重启你的应用。
健康检查的 URL 包括你的应用首页(
/
)和 Java SDK 负责处理的/__engine/1/ping
,只要 两者之一 返回了 HTTP200
的响应,就视作成功。因此请确保你的程序使用了 Java SDK,或你的应用 首页能够正常地返回 HTTP200
响应。除此之外,为了支持云引擎的云函数和 Hook 功能,管理程序会使用/1.1/functions/_ops/metadatas
这个 URL 和 Java SDK 交互,请确保将这个 URL 交给 Java SDK 处理,或 返回一个 HTTP404
表示不使用云函数和 Hook 相关的功能。如果未使用 LeanEngine Java SDK,则需要自己实现该 URL 的处理,比如这样:
用户状态管理
云引擎提供了一个
EngineSessionCookie
组件,用 Cookie 来维护用户(AVUser
)的登录状态,要使用这个组件可以在初始化时添加下列代码:EngineSessionCookie
的构造函数参数包括:fetch
当前登录的AVUser
对象。默认为false
。如果设置为true
,每个 HTTP 请求都将发起一次 LeanCloud API 调用来fetch
用户对象。如果设置为false
,默认只可以访问AVUser.getCurrentUser()
的id
(_User
表记录的objectId
)和sessionToken
属性,你可以在需要时再手动fetch
整个用户。你可以这样简单地实现一个具有登录功能的站点:
登录
登出
Profile 页面
一个简单的登录页面(
login.jsp
)可以是这样:实现常见的网站功能
发送 HTTP 请求
云引擎 Java 环境可以使用
URL
或者是HttpClient
等基础类 ,不过我们推荐使用okhttp
等第三方库来处理 HTTP 请求:获取客户端 IP
如果你想获取客户端的 IP,可以直接从用户请求的 HTTP 头的
x-real-ip
字段获取,示例代码如下:注意,国内节点的云引擎应用,如果启用了边缘节点加速功能,那么由于边缘节点的限制,无法获取客户端 IP。
文件上传
托管在 LeanEngine 的网站项目可以直接使用内置的 LeanCloud Java SDK 的 API 文件相关的接口直接处理文件的上传。
假设前端 HTML 代码如下:
接下来定义文件上传的处理函数,构建一个
Form
对象,并将req
作为参数进行解析,会将请求中的文件保存到临时文件目录,并构造files
对象:CSRF Token
如果你的云引擎应用使用 Cookie 作为鉴权方式的话(例如使用 SDK 的
CookieSession
中间件),那么就有受到 CSRF 攻击的风险,将会允许其他站点伪造带有正确 Cookie 的恶意请求。业界通常使用 CSRF Token 来防御 CSRF 攻击,你需要传递给客户端一个随机字符串(即 CSRF Token,可通过 Cookie 传递),客户端在每个有副作用的请求中都要将 CSRF 包含在请求正文或 Header 中,服务器端需要校验这个 CSRF Token 是否正确。
重定向到 HTTPS
为了安全性,我们可能会为网站加上 HTTPS 加密传输。我们的 LeanEngine 支持网站托管,同样会有这样的需求。因此我们在 LeanEngine 中提供了一个 middleware 来强制网站通过 HTTPS 访问,你只要这样:
部署并发布到生产环境之后,访问你的 LeanEngine 网站都会强制通过 HTTPS 访问。
部署与发布
命令行部署
在你的项目根目录运行:
使用命令行工具可以非常方便地部署、发布应用,查看应用状态,查看日志,甚至支持多应用部署。具体使用请参考 命令行工具指南。
依赖缓存
云引擎实现了一个缓存机制来加快构建的速度,所谓构建就是指你的应用在云引擎上安装依赖的过程,在每次构建时,如果依赖没有新增或者删减,那么就直接使用上次安装的依赖,只将新的应用代码替换上去。
依赖缓存也会因为很多原因失效,因此不保证每次构建都可以利用上缓存。
如果你遇到了与依赖安装有关的问题,可以在控制台部署时勾选「下载最新依赖」,或通过命令行工具部署时添加
--no-cache
选项。Git 部署
除此之外,还可以使用 git 仓库部署。你需要将项目提交到一个 git 仓库,我们并不提供源码的版本管理功能,而是借助于 git 这个优秀的分布式版本管理工具。我们推荐你使用 GitHub、Coding 或者 码云 这样第三方的源码托管网站,也可以使用你自己搭建的 git 仓库(比如 GitLab)。
你需要先在这些平台上创建一个项目(如果已有代码,请不需要选择「Initialize this repository with a README」),在网站的个人设置中填写本地机器的 SSH 公钥(以 GitHub 为例,在 Settings > SSH and GPG keys 中点击 New SSH key),然后在项目目录执行:
然后到云引擎的设置界面填写你的 Git 仓库地址,如果是公开仓库建议填写 HTTPS 地址,例如
https://github.com/<username>/<repoName>.git
。如果是私有仓库需要填写 SSH 地址(
git@github.com:<username>/<repoName>.git
),还需要你将云引擎分配给你的公钥填写到第三方托管平台的 Deploy keys 中,以 GitHub 为例,在项目的 Settings > Deploy keys 中点击 Add deploy key。设置好之后,今后需要部署代码时就可以在云引擎的部署界面直接点击「部署」了,默认会部署
master
分支的代码,你也可以在部署时填写分支、标签或具体的 Commit。 如果仓库使用了 submodule,云引擎也会自动拉取 submodule。如果希望 push 到项目的 Git 仓库的特定分支后自动触发云引擎部署,可以在应用的 控制台 > 云引擎 > 部署 > git 部署 > 自动部署 查看 deploy token 和 webhook 地址。 控制台显示的 deploy token 可以用来构造 HTTP 请求触发部署。 在控制台填写项目仓库的分支名称,并选择云引擎的运行环境后,控制台会生成相应的 webhook 地址。 该地址收到任意 POST 请求后,会部署指定分支的代码到指定的运行环境。
例如,在 GitHub 代码仓库的 Settings > Webhooks > Payload URL 填写生成的 webhook 后(其他选项均使用默认值,不用修改),下次 push 到项目仓库的 任意 分支,云引擎会自动根据 指定 分支更新代码,重新部署。之所以 push 到任意分支都会触发重新部署,是因为 GitHub 的 webhook 触发事件设置粒度较粗,不能指定仅在 push 到特定分支时触发 webhook。另一方面,云引擎也没有适配具体的托管平台,不会根据 GitHub 提交的 POST 内容中的分支信息决定是否重新部署。 不过,你可以使用 GitHub Action 更精细地控制部署时机,具体可以参考控制台显示的示例。
预备环境和生产环境
默认情况,云引擎只有一个「生产环境」。在生产环境中有一个「体验实例」来运行应用。
当生产环境的体验实例升级到「标准实例」后会有一个额外的「预备环境」。两个环境所访问的都是同样的数据,你可以用预备环境测试你的云引擎代码,每次修改先部署到预备环境,测试通过后再发布到生产环境;如果你希望有一个独立数据源的测试环境,建议单独创建一个应用。
在云引擎托管的网站需要绑定域名才能访问。 以
stg-
开头的域名会自动绑定到预备环境。如果访问云引擎遇到「Application not Found」的错误,通常是因为对应的环境还没有部署代码。例如应用可能没有预备环境,或应用尚未发布代码到生产环境
有些时候你可能需要知道当前云引擎运行在什么环境(开发环境、预备环境或生产环境),从而做不同的处理:
你还可以在 SDK 中指定客户端将请求所发往的环境:
云端环境
系统级依赖
在云引擎的线上环境中,你可以通过
leanengine.yaml
文件的systemDependencies
部分来自定义系统级依赖:目前支持的选项包括:
ffmpeg
一个音视频处理工具库。imagemagick
一个图片处理工具库。fonts-wqy
文泉驿点阵宋体、文泉驿微米黑,通常和phantomjs
或chrome-headless
配合来显示中文。fonts-noto
思源黑体(体积较大)。phantomjs
一个无 UI 的 WebKit 浏览器(该项目已停止维护)。chrome-headless
一个无 UI 的 Chrome 浏览器(体积很大,会显著增加部署耗时,运行时也会消耗大量 CPU 和内存;如果使用puppeter
的话,需要给puppeteer.launch
传递这些参数:{executablePath: '/usr/bin/google-chrome', args: ['--no-sandbox', '--disable-setuid-sandbox']}
;暂不支持 Java)。node-canvas
安装node-canvas
所需要的系统级依赖(你仍需要安装node-canvas
)。python-talib
金融市场数据分析库。注意添加系统依赖将会拖慢部署速度,因此请不要添加未用到的依赖。
环境变量
云引擎平台默认提供下列环境变量供应用使用:
LEANCLOUD_APP_ID
LEANCLOUD_APP_KEY
LEANCLOUD_APP_MASTER_KEY
LEANCLOUD_APP_ENV
development
(一般指本地开发)。stage
。production
。LEANCLOUD_APP_PORT
LEANCLOUD_API_SERVER
https://api.leancloud.cn
)。该值会因为所在数据中心等原因导致不一样,所以使用 REST API 请求存储服务或 LeanCloud 其他服务时请使用此环境变量的值。在云引擎中 不要 直接使用https://api.leancloud.cn
。LEANCLOUD_APP_GROUP
LEANCLOUD_REGION
CN
或US
,分别表示国内版和国际版。LEANCLOUD_VERSION_TAG
旧版云引擎使用的以
LC_
开头的环境变量(如LC_APP_ID
)已经被弃用。为了保证代码兼容性,LC_
变量在一段时间内依然有效,但未来可能会完全失效。为了避免报错,建议使用LEANCLOUD_
变量来替换。你也可以在 控制台 > 云引擎 > 设置 > 自定义环境变量 页面中添加自定义的环境变量。其中名字必须是字母、数字、下划线且以字母开头,值必须是字符串,修改环境变量后会在下一次部署时生效。
按照一般的实践,可以将一些配置项存储在环境变量中,这样可以在不修改代码的情况下,修改环境变量并重新部署,来改变程序的行为;或者可以将一些第三方服务的 Secret Key 存储在环境变量中,避免这些密钥直接出现在代码中。
云引擎运行环境默认提供的环境变量无法被自定义环境变量覆盖(覆盖无效)。
默认情况下,应用在运行阶段才能够读取到内置环境变量和自定义环境变量。 如果希望在安装依赖或编译阶段就能读取到这些环境变量,需要在
leanengine.yaml
里设置:负载均衡和边缘节点
在云引擎上,用户的请求会先经过负载均衡组件,然后到达你的应用。 负载均衡组件会处理 HTTPS 加密、对响应进行压缩等一般性工作,因此你不必在你的应用中添加 HTTPS 或 gzip 相关的功能。 也因为 HTTPS 加密是在负载均衡层面处理的,所以通常部署在云引擎上的 web 框架获取的请求 URL 总是使用 HTTP 协议,建议通过
X-Forwarded-Proto
HTTP 头来判断原请求是通过 HTTP 还是 HTTPS 访问的。负载均衡同时限制了请求不能超过 100 MB(包括直接上传文件到云引擎)、请求处理不得超过 60 秒,WebSocket 60 秒无数据会被断开连接。
国内节点未绑定独立 IP 的云引擎默认为纯静态站点优化。请求会先经过边缘节点,再视缓存命中情况回源到负载均衡组件,最后到达你的应用。 边缘节点额外限制了请求不能超过 60 MB、请求处理不得超过 10 秒,另外边缘节点不支持 WebSocket 请求和 HTTP PATCH 方法,也不支持获取客户端 IP。 因此,如果您在国内节点云引擎托管动态网站,我们建议您绑定独立 IP,使用独立入口,不经过边缘节点,自然也就没有上述限制。
文件系统
你可以向
/home/leanengine
或/tmp
目录写入临时文件,最多不能超过 1 GB。云引擎每次部署都会产生一个新的容器,即使不部署系统偶尔也会进行一些自动调度,这意味着你 不能将本地文件系统当作持久的存储,只能用作临时存储。
如果你写入的文件体积较大,建议在使用后自动删除他们,否则如果占用磁盘空间超过 1 GB,继续写入文件可能会收到类似
Disk quota exceeded
的错误,这种情况下你可以重新部署一下,这样文件就会被清空了。日志
在 控制台 > 云引擎 > 日志 中可以查看云引擎的部署和运行日志,还可以通过日志级别进行筛选。
你还可以 通过命令行工具来导出 最近七天的日志到本地文件,方便进行进一步的分析和统计。
日志单行最大 4096 个字符,多余部分会被丢弃;日志输出频率大于 600 行/分钟,多余的部分会被丢弃。
云引擎的访问日志(Access Log)可在 控制台 > 云引擎 > 访问日志 中导出,通过控制台下载经过打包的日志。
时区
在云引擎的中国区系统默认使用北京时间(
Asia/Shanghai
),美国区默认使用 UTC 时间。出入口 IP 地址
如果开发者希望在第三方服务平台(如微信开放平台)上配置 IP 白名单而需要获取云引擎的入口或出口 IP 地址,请进入 控制台 > 云引擎 > 设置 > 出入口 IP 来自助查询。
我们会尽可能减少出入口 IP 的变化频率,但 IP 突然变换的可能性仍然存在。因此在遇到与出入口 IP 相关的问题,我们建议先进入控制台来核实一下 IP 列表是否有变化。
备案与自定义域名
根据法律法规和有关部门的要求,使用云引擎网站托管服务需要 绑定自有域名。