# 服务间内网调用

云托管支持服务间以内网域名的方式进行内网调用，提供安全性高、时延低、效率高的内网通讯服务。每个服务开启内网访问后，均会分配一个内网域名。因分配内网域名需当前服务重新部署发布才能生效，故在开启内网方式时，将自动触发一次部署发布。

## 操作路径

### 1. 新建服务

新建服务时，可直接开启内网访问，部署发布后将自动分配内网域名。

![](https://res.wx.qq.com/op_res/PnElNTNwOTIRq-QHty4G90Tq0tiKoXHYC6pPebDTxa1hg7e9yhH1yi2Fk3rX8JbyHrZP4PHBhoeLzZzHFG6NXw)

### 2. 已有服务

前往「服务列表 - 目标服务 - 服务设置」中进行开启

![](https://res.wx.qq.com/op_res/PnElNTNwOTIRq-QHty4G93NEcA3LlgqXb0nRULA2fKdBxgRrn3xUGyZtwOAT-BT_lSw3c-zlBbC4pO_FvBlQyA)

点击开启，二次弹窗确认后，将自动触发一次服务的部署发布，不需要再次点击页面下方的「保存」按钮。发布完成后，将自动获取内网域名。

## 示例

> 注意：本示例中部署的 Redis 仅保留在容器临时存储中，不具有持久化能力，重新部署/扩缩容后会丢失数据，请勿在有持久化存储需求场景下使用。

在本教程中会展示如何结合内网调用能力，在云托管中部署一个 Redis 数据库，并使用其作为 Express 服务器的 Session 存储。

### 第一步：创建项目

创建一个文件夹（express-redis-session），并初始化 npm 项目。

```bash
mkdir express-redis-session && cd express-redis-session
npm init -y
```

### 第二步：安装 Redis 和 Express 依赖

直接执行安装命令，等待依赖安装完成。

```bash
npm i -S express redis connect-redis express-session
```

### 第三步：创建 Redis 服务并调整规格

在云托管控制台，点击「新建服务」，创建一个名为 `redis` 的服务，开启内网访问，关闭公网访问。

![](https://res8.wxqcloud.qq.com.cn/wxdoc/12b71cf3-fb25-4101-a96f-f6f9a47cd4dc.png)

部署时，选择「从地址拉取镜像」，镜像地址填 `redis:latest`，端口填 `6379`。

![](https://res8.wxqcloud.qq.com.cn/wxdoc/d3e1985b-5452-4c9d-af32-e9f48c8bf6f4.png)

点击发布，发布完成后，点击「服务设置」，修改容器规格为 0.25 CPU，修改实例数量为 1-1，保存修改，等待发布完成即可。

![](https://res8.wxqcloud.qq.com.cn/wxdoc/a18c6066-5926-4442-b5fd-fe36ac38b694.png)

### 第四步：复制内网域名，创建 index.js

在 `redis` 服务内复制内网域名，在第一步创建的文件夹内创建 `index.js` 并填入如下内容，将下面代码中的内网域名替换为第三步中复制的内网域名：

```js
var express = require('express')
var parseurl = require('parseurl')
var session = require('express-session')
const redis = require('redis')
const RedisStore = require('connect-redis').default

var client = redis.createClient({
  url: 'redis://替换为内网域名:6379',
})
client.connect().catch(console.error)

var app = express()

app.use(
  session({
    store: new RedisStore({ client: client }),
    secret: 'forest squirrel',
    resave: false,
    saveUninitialized: true,
  })
)

app.use(function (req, res, next) {
  if (!req.session.views) {
    req.session.views = {}
  }

  // get the url pathname
  var pathname = parseurl(req).pathname

  // count the views
  req.session.views[pathname] = (req.session.views[pathname] || 0) + 1
  next()
})

app.get('/', function (req, res, next) {
  res.send('you viewed this page ' + req.session.views['/'] + ' times')
})

app.get('/foo', function (req, res, next) {
  res.send('you viewed this page ' + req.session.views['/foo'] + ' times')
})

app.get('/bar', function (req, res, next) {
  res.send('you viewed this page ' + req.session.views['/bar'] + ' times')
})

app.listen(80, function () {
  console.log('Example app listening on port 80!')
})

```

创建 Dockerfile，内容如下：

> 使用 @wxcloud/cli 能够更快更方便的容器化项目，只需要执行 `wxcloud migrate` 即可一键完成 Dockerfile 的编写，前往 https://cloud.weixin.qq.com/cli/ 了解更多。

```dockerfile
FROM node:lts-alpine

# 设置容器内的当前目录
WORKDIR /app

# 使用速度更快的国内镜像源
RUN npm config set registry https://registry.npmmirror.com

# 将这些文件拷贝到容器中
COPY package.json package-lock.json ./

# 安装依赖
RUN npm ci

# 将包括源文件在内的所有文件拷贝到容器中（在 .dockerignore 中的文件除外）
COPY . .

# 设置环境变量
ENV NODE_ENV=production HOST=0.0.0.0

# 运行项目
CMD ["node", "index.js"]

# 服务暴露的端口
EXPOSE 80
```

在微信云托管中新建一个服务，开启「公网访问」，使用代码包上传部署，上传文件夹，等待部署完成。

![](https://res8.wxqcloud.qq.com.cn/wxdoc/e967046f-82be-42dd-ae00-f0cde4893f26.png)

### 第五步：查看页面效果

部署完成后，点击公网链接，即可查看效果：

![](https://res8.wxqcloud.qq.com.cn/wxdoc/5fc78026-431e-4ad5-ba56-5171f71a302e.png)

可以看到，访问次数已被写入到 Redis 数据库中，刷新时，可见到次数增加。

### 注意事项

服务间内网调用，端口为服务部署发布时填写的端口，其他端口不可使用。
