共计 4421 个字符,预计需要花费 12 分钟才能阅读完成。
导读 | 前文谈到了云原生应用在部署架构中需要考虑的重要问题。文本将介绍一个常见的应用架构模式来提升应用的可用性和可伸缩性 – 分布式会话管理。并利用 Docker 和阿里云容器服务在本地和云端进行了示例应用的部署和验证。 |
前文谈到了云原生应用在部署架构中需要考虑的重要问题。文本将介绍一个常见的应用架构模式来提升应用的可用性和可伸缩性 – 分布式会话管理。
随着业务增长,Web 应用也从单节点部署演变为集群部署。这时候除了需要为应用服务器增加负载均衡之外,也要解决会话(session)管理的问题。Session 在应用中常被用于存储用户相关的数据。在高可用系统中,如果一台应用服务宕机,其他服务器需要能够接管当前活跃的会话,继续为用户提供服务。所以我们必须提供分布式的会话管理能力。
Spring/Spring Boot 应用中利用 Spring Session 配合 Redis 是一个流行的分布式的会话管理方案,它有如下几个优点:
- 将 session 所持久化状态从应用服务器本地内存卸载到外部 Redis 服务中,可以提升应用的可用性
- 应用服务器是无状态的,满足 12-factor 的要求,可以更好地支持应用水平扩展
关于 Spring Session 的信息可以从官方文档获得
首先从 Github 获得示例代码
class="hljs stata" data-language="">git clone https://github.com/denverdino/docker-spring-boot-sample-session-redis
cd docker-spring-boot-sample-session-redis
本工程基于 Spring Boot 使用 Redis 会话存储的官方示例,并做简单调整如下:
其中 /src/main/resources/application.properties 内容:
class="hljs stylus" data-language="">spring.session.store-type=redis
server.session.timeout=5
spring.redis.host=redis
spring.redis.port=6379
它会配置基于 Redis 的分布式会话存储支持,会话超时时间为“5”秒,Redis 服务域名为“redis”,端口“6379”。
我们再查看项目的 Maven 配置文件 pom.xml
class="hljs dust" data-language=""><?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<!-- Your own application should inherit from spring-boot-starter-parent -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.1.RELEASE</version>
</parent>
<artifactId>spring-boot-sample-session-redis</artifactId>
<name>Spring Boot Session Redis Sample</name>
<description>Spring Boot Session Redis Sample</description>
<url>http://projects.spring.io/spring-boot/</url>
<organization>
<name>Pivotal Software, Inc.</name>
<url>http://www.spring.io</url>
</organization>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>0.4.13</version>
<configuration>
<imageName>registry.cn-hangzhou.aliyuncs.com/denverdino/spring-boot-session-redis</imageName>
<baseImage>openjdk:8-jre</baseImage>
<entryPoint>["java", "-jar", "/${project.build.finalName}.jar"]</entryPoint>
<resources>
<resource>
<targetPath>/</targetPath>
<directory>${project.build.directory}</directory>
<include>${project.build.finalName}.jar</include>
</resource>
</resources>
</configuration>
</plugin>
</plugins>
</build>
</project>
其中它除了声明了对 Spring Boot 框架的支持,还添加了来自 Spotify 的 docker-maven-plugin
构建应用的 Docker 镜像
我们可以来用 maven 命令来构建 Spring Boot 示例应用(参数是为了跳过单元测试)
class="hljs stylus" data-language="">mvn package -Dmaven.test.skip=true
也可以利用 maven 命令构建示例应用的 Docker 镜像
class="hljs armasm" data-language="">mvn package docker:build -Dmaven.test.skip=true
注:关于“docker-maven-plugin”插件的更多信息,可以参考容器化 Spring Boot 应用一文
构建镜像完成,可以使用如下 docker-compose.yml 模板来在本地部署和测试应用。其中 web 服务会启动 Spring Boot 测试应用,并利用容器链接通过“redis”别名来访问 redis 服务中的 Redis 容器
class="hljs vim" data-language="">web:
image: registry.cn-hangzhou.aliyuncs.com/denverdino/spring-boot-session-redis
ports:
- 8080:8080
links:
- redis:redis
redis:
image: redis:3
执行 docker-compose up 命令之后,我们就会看到“redis”容器和“web”应用容器相继启动
我们可以通过浏览器来访问 http://localhost:8080/ 测试应用。如果会话不存在或会话超时(5 秒钟),应用会生成一个 UUID 保存在会话中并返回;如果会话存在,则会直接返回会话中保存的 UUID。
阿里云容器服务提供了对分布式的 Docker 应用的部署和管理能力。我们可以简单地扩展之前的 Docker Compose 模板来在云端部署应用。
class="hljs vim" data-language="">web:
image: registry.cn-hangzhou.aliyuncs.com/denverdino/spring-boot-session-redis
labels:
aliyun.scale: "3"
aliyun.routing.port_8080: spring-boot
links:
- redis:redis
redis:
image: redis:3
注:
- 通过 aliyun.xxx 标签声明了,web 应用由 3 个容器组成应用集群,并可以通过虚拟域名“spring-boot”进行访问
- 通过路由服务来访问应用是无需使用 ports 对容器端口进行宿主机端口映射的部署之后,web 服务在控制台的截图如下,可以直接点击访问端点来验证应用。
在云原生应用中,分布式会话管理是一个重要的应用模式。本文利用 Docker 和阿里云容器服务在本地和云端进行了示例应用的部署和验证。
如果大家有兴趣,还可以将容器模板中的 Redis 镜像替换成阿里云提供的 Redis 服务,这样可以在生产系统中提供更好的可用性和和可伸缩性。可以参考在阿里云容器服务中使用 RDS