基于微服务构建Web消息应用的全流程指南
立即解锁
发布时间: 2025-08-14 00:53:42 阅读量: 1 订阅数: 3 


Python编程蓝图:构建九大项目实战
# 基于微服务构建Web消息应用的全流程指南
## 1. 消息存储方案选择
在开发消息应用时,我们需要存储临时消息。虽然可以使用关系型数据库(如PostgreSQL),但为了这么简单的文本数据去设计和维护数据库,显得有些大材小用。因此,我们选择Redis作为消息存储方案。
### 1.1 Redis简介
Redis是一种内存数据存储系统,它将整个数据集存储在内存中,这使得读写操作比关系型数据库快得多,非常适合不需要持久化的数据。而且,我们无需定义复杂的数据库模式就可以存储数据,对于不需要复杂查询的场景来说十分合适。在我们的消息应用中,只需要一个能存储、获取和过期消息的数据存储系统,Redis正好满足需求。
### 1.2 启动Redis容器
在终端中执行以下命令启动Redis容器:
```bash
$ docker run -d -p 6379:6379 --name redis redis
```
参数说明:
- `-d`:指定以守护进程模式(后台进程)运行容器。
- `-p`:将容器的6379端口暴露到本地机器,这是Nameko与Redis通信所必需的。
- `--name`:将容器命名为`redis`。
可以通过以下命令检查新的Redis容器是否正在运行:
```bash
$ docker ps
```
### 1.3 安装Python Redis客户端
为了通过Python与Redis进行交互,需要安装Python Redis客户端。可以通过以下两种方式安装:
- 修改`base.in`文件,添加`redis`,然后重新编译生成新的`base.txt`文件。
- 直接运行`pip install redis`。
### 1.4 Redis命令使用
以下是一些对消息应用有用的Redis命令:
| 命令 | 描述 |
| ---- | ---- |
| SET | 设置给定键的值为给定字符串,还可以设置过期时间(秒或毫秒) |
| GET | 获取给定键存储的数据值 |
| TTL | 获取给定键的剩余生存时间(秒) |
| PTTL | 获取给定键的剩余生存时间(毫秒) |
| KEYS | 返回数据存储中的所有键列表 |
可以使用`redis-cli`来尝试这些命令,步骤如下:
1. 在终端中执行以下命令登录到容器:
```bash
docker exec -it redis /bin/bash
```
2. 在同一终端窗口中运行以下命令访问`redis-cli`:
```bash
redis-cli
```
以下是一些使用示例:
```plaintext
127.0.0.1:6379> SET msg1 hello
OK
127.0.0.1:6379> GET msg1
"hello"
127.0.0.1:6379> SET msg2 "hi there"
OK
127.0.0.1:6379> GET msg2
"hi there"
127.0.0.1:6379> KEYS *
1) "msg2"
2) "msg1"
127.0.0.1:6379> SET msg3 "this message will die soon" EX 15
OK
127.0.0.1:6379> TTL msg3
(integer) 10
127.0.0.1:6379> PTTL msg3
(integer) 6080
127.0.0.1:6379> GET msg3
"this message will die soon"
127.0.0.1:6379> GET msg3
(nil)
```
### 1.5 Nameko依赖提供者
在构建微服务时,Nameko鼓励使用依赖提供者与外部资源(如数据库、服务器等)进行通信。通过使用依赖提供者,可以隐藏特定于该依赖的逻辑,使服务层代码保持简洁,并且与外部资源的交互细节无关。这样的结构还允许我们轻松地在其他服务中交换或重用依赖提供者。Nameko提供了一系列开源的依赖提供者,可参考:http://url.marcuspen.com/nam-ext 。
### 1.6 添加Redis依赖提供者
由于Redis是我们应用的外部资源,需要为其创建一个依赖提供者。
#### 1.6.1 设计客户端
在`temp_messenger`文件夹内创建一个名为`dependencies`的新文件夹,并在其中创建一个新文件`redis.py`。以下是创建Redis客户端的代码:
```python
from redis import StrictRedis
class RedisClient:
def __init__(self, url):
self.redis = StrictRedis.from_url(
url, decode_responses=True
)
def get_message(self, message_id):
message = self.redis.get(message_id)
if message is None:
raise RedisError(
'Message not found: {}'.format(message_id)
)
return message
class RedisError(Exception):
pass
```
代码说明:
- `__init__`方法:创建Redis客户端并将其赋值给`self.redis`。`StrictRedis.from_url`允许我们使用单个字符串指定主机、端口和数据库编号,例如`redis://localhost:6379/0`,这在将其存储在`config.yaml`中时更加方便。`decode_responses`参数将从Redis获取的数据自动转换为Unicode字符串,默认情况下数据是以字节形式获取的。
- `get_message`方法:根据给定的消息ID(作为Redis键)获取消息。如果键不存在,将抛出`RedisError`异常。
#### 1.6.2 创建依赖提供者
在`redis.py`文件中,更新导入语句并实现Nameko依赖提供者:
```python
from nameko.extensions import DependencyProvider
from redis import StrictRedis
class RedisClient:
def __init__(self, url):
self.redis = StrictRedis.from_url(
url, decode_responses=True
)
def get_message(self, message_id):
message = self.redis.get(message_id)
if message is None:
raise RedisError(
'Message not found: {}'.format(message_id)
)
return message
class RedisError(Exception):
pass
class MessageStore(DependencyProvider):
def setup(self):
redis_url = self.container.config['REDIS_URL']
self.client = RedisClient(redis_url)
def stop(self):
del self.client
def get_dependency(self, worker_ctx):
return self.client
```
方法说明:
- `setup`方法:在Nameko服务启动前调用,从`config.yaml`中获取Redis URL,并创建一个新的`RedisClient`实例。
- `stop`方法:在Nameko服务开始关闭时调用。
- `get_dependency`方法:所有依赖提供者都需要实现此方法。当入口点触发时,Nameko会创建一个工作进程,并将每个依赖的`get_dependency`结果注入到工作进程中。在我们的例子中,工作进程将可以访问`RedisClient`的实例。
### 1.7 创建消息服务
在`service.py`文件中,使用新的Redis依赖提供者创建一个
0
0
复制全文
相关推荐










