🔹 1. 确认 Redis 已经在监听 6379 端口
先看 Redis 是否在跑:
| ps -ef | grep redis |
| ---------------------- |
确认端口:
| netstat -tulnp | grep 6379 |
| ----------------------------- |
| ss -tulnp | grep 6379 |
| ------------------------ |
如果有输出类似:
tcp LISTEN 0 128 0.0.0.0:6379 0.0.0.0:* users:(("redis-server",pid=1234,fd=6)) |
|---|
说明 Redis 已经在监听 6379。
🔹 2. 修改 Redis 配置(允许外部访问)
编辑配置文件(一般在 /etc/redis/redis.conf 或 /etc/redis.conf):
vim /etc/redis/redis.conf |
|---|
找到这一行:
改成:
确认 protected-mode 是关闭的(如果你需要远程访问):
保存后重启 Redis:
🔹 3. 开放防火墙端口(Linux)
如果你用的是 firewalld:
firewall-cmd --zone=public --add-port=6379/tcp --permanent |
|---|
如果你用的是 ufw(Ubuntu 常见):
iptables(老系统)
iptables -A INPUT -p tcp --dport 6379 -j ACCEPT |
|---|
🔹 4. 云服务器安全组
如果你是在 阿里云 / 腾讯云 / AWS / GCP 上,要去对应的 安全组规则 里,把 6379 端口(TCP) 放行。否则外网访问不到。
🔹 5. 测试是否能连通
在远程机器上执行:
如果能连上,就说明端口已经开通。
或者直接用 redis-cli:
redis-cli -h <服务器IP> -p 6379 |
|---|
⚠️ 安全提示:
6379 端口不要直接裸奔暴露在公网,否则很容易被攻击!
✅ 最好做法:
- 开启密码认证(在 redis.conf 配置
requirepass yourpassword)
- 或者只允许内网访问(不要
bind 0.0.0.0,改成你的内网 IP)。
好👌 阿杰,我给你一份 Redis 远程访问安全配置清单,这样你开了 6379 端口也能比较安全。
🔐 Redis 远程访问安全配置清单
1. 设置密码认证
编辑 redis.conf(路径一般是 /etc/redis/redis.conf):
requirepass StrongPassword123! |
|---|
⚠️ 建议使用强密码(大小写 + 数字 + 特殊符号,至少 12 位)。
测试:
redis-cli -h <服务器IP> -p 6379 -a StrongPassword123! |
|---|
2. 限制绑定的 IP
如果只允许某些服务器连,就不要 0.0.0.0,改成指定内网 IP:
bind 127.0.0.1 192.168.1.100 |
|---|
这样就只允许本机和 192.168.1.100 访问。
3. 配置防火墙白名单
firewalld
firewall-cmd --permanent --add-rich-rule=' |
|---|
``source address="192.168.1.100" |
|---|
``port protocol="tcp" port="6379" accept' |
|---|
UFW (Ubuntu)
ufw allow from 192.168.1.100 to any port 6379 |
|---|
4. 关闭危险命令(防止恶意利用)
有些命令可能被攻击者用来搞破坏,比如 FLUSHALL, CONFIG, SHUTDOWN。
在 redis.conf 里禁用:
rename-command FLUSHALL "" |
|---|
rename-command SHUTDOWN "" |
|---|
5. 使用 TLS 加密(可选)
Redis 6.0+ 支持 TLS/SSL,可以加密数据传输。
配置证书后,远程访问就不会明文传输密码。
6. 使用守护进程 / supervisor 监控
保持 Redis 在后台安全运行:
7. 定期检查日志和端口
查看是否有异常连接:
| ss -atpn | grep 6379 |
| ----------------------- |
查看 Redis 日志(一般在 /var/log/redis/redis-server.log)。
✅ 总结:
- 必须做:
requirepass 设置密码
- 最好做:绑定指定 IP + 防火墙白名单
- 更安全:禁用危险命令 + TLS
好嘞,阿杰 👍 我给你写一份 安全优化后的 redis.conf 配置示例,你可以直接套用(记得把密码、IP 换成你自己的)。
✅ Redis 安全配置示例(redis.conf)
######################################## |
|---|
######################################## |
|---|
logfile /var/log/redis/redis-server.log |
|---|
######################################## |
|---|
######################################## |
|---|
requirepass StrongPassword123! |
|---|
######################################## |
|---|
######################################## |
|---|
# 如果只允许 192.168.1.100 访问,可以在防火墙层面控制 |
|---|
# bind 127.0.0.1 192.168.1.100 |
|---|
######################################## |
|---|
######################################## |
|---|
rename-command FLUSHALL "" |
|---|
rename-command FLUSHDB "" |
|---|
rename-command SHUTDOWN "" |
|---|
######################################## |
|---|
######################################## |
|---|
# 禁用外部配置保存目录的写权限(需在系统层面 chmod) |
|---|
# chmod 700 /var/lib/redis |
|---|
######################################## |
|---|
######################################## |
|---|
# tls-cert-file /etc/ssl/redis/redis.crt |
|---|
# tls-key-file /etc/ssl/redis/redis.key |
|---|
# tls-ca-cert-file /etc/ssl/redis/ca.crt |
|---|
🚀 使用方法
- 编辑配置文件:
vim /etc/redis/redis.conf (替换内容为上面示例,改掉密码)
- 重启 Redis:
systemctl restart redis
- 测试远程连接:
redis-cli -h <服务器IP> -p 6379 -a StrongPassword123!
⚠️ 建议:
- 如果是云服务器,还需要 安全组放行 6379。
- 不建议完全对公网暴露,最好只开放给内网或者指定 IP。
👌 阿杰,那我给你整理一份 Redis 6379 端口双保险安全方案(云服务器安全组 + Linux 防火墙) ,确保只有你信任的 IP 能访问。
🔐 Redis 6379 端口双保险方案
1️⃣ 云服务器安全组配置
以 阿里云 / 腾讯云 / AWS / GCP 为例:
-
放行规则:
- 协议:TCP
- 端口:6379
- 源 IP:你的信任 IP(比如
123.45.67.89)
⚠️ 千万不要用 0.0.0.0/0(所有人都能访问),否则 Redis 很容易被攻击。
2️⃣ Linux 防火墙配置
🔹 Firewalld(CentOS / RHEL 常见)
只允许 123.45.67.89 访问:
firewall-cmd --permanent --add-rich-rule=' |
|---|
``source address="123.45.67.89" |
|---|
``port protocol="tcp" port="6379" accept' |
|---|
验证:
firewall-cmd --list-rich-rules |
|---|
🔹 UFW(Ubuntu 常见)
只允许 123.45.67.89 访问:
ufw allow from 123.45.67.89 to any port 6379 |
|---|
检查:
🔹 iptables(老系统)
iptables -A INPUT -p tcp -s 123.45.67.89 --dport 6379 -j ACCEPT |
|---|
iptables -A INPUT -p tcp --dport 6379 -j DROP |
|---|
3️⃣ Redis 配置安全项(配合使用)
在 redis.conf 中:
requirepass StrongPassword123! # 设置密码 |
|---|
protected-mode no # 关闭保护模式(否则只能本机访问) |
|---|
禁用危险命令(避免被攻击者利用):
rename-command FLUSHALL "" |
|---|
rename-command FLUSHDB "" |
|---|
rename-command SHUTDOWN "" |
|---|
4️⃣ 验证
在外部客户端测试连接:
redis-cli -h <服务器公网IP> -p 6379 -a StrongPassword123! |
|---|
如果非白名单 IP 访问,会提示:
Could not connect to Redis at <IP>:6379: Connection refused |
|---|
✅ 总结:
- 云服务器安全组:第一道防线
- Linux 防火墙(firewalld/ufw/iptables) :第二道防线
- Redis 密码 & 禁用危险命令:第三道防线
这样,Redis 即使开在公网,也能最大限度降低风险。
阿杰,好的 👍 我来给你一个非常详尽的 Python typing 模块讲解和示例,帮助你快速掌握类型注解的常见用法。
🐍 Python typing 模块详解
typing 模块是 Python 用于 类型注解(type hints) 的标准库,主要用于 静态类型检查(不会影响运行时,但可以让 IDE / 工具提前发现错误)。
1️⃣ 基础类型注解
from typing import List, Dict, Tuple, Set, Union, Optional |
|---|
2️⃣ 容器类型
from typing import List, Dict, Tuple, Set |
|---|
numbers: List[int] = [1, 2, 3] |
|---|
person: Dict[str, int] = {"age": 20, "score": 95} |
|---|
point: Tuple[int, int] = (10, 20) |
|---|
unique_values: Set[str] = {"a", "b", "c"} |
|---|
3️⃣ Union & Optional
from typing import Union, Optional |
|---|
value: Union[int, str] = "hello" |
|---|
# Optional:可能是某种类型,也可能是 None |
|---|
maybe_number: Optional[int] = None |
|---|
Optional[int] 等价于 Union[int, None]
4️⃣ 函数注解
from typing import List, Dict |
|---|
def add(a: int, b: int) -> int: |
|---|
def get_names(ids: List[int]) -> Dict[int, str]: |
|---|
``return {i: f"user{i}" for i in ids} |
|---|
5️⃣ Callable(函数作为参数)
from typing import Callable |
|---|
def execute(func: Callable[[int], str], value: int) -> str: |
|---|
def stringify(x: int) -> str: |
|---|
print(execute(stringify, 123)) # "123" |
|---|
6️⃣ Any(任意类型)
7️⃣ TypeVar(泛型)
from typing import TypeVar, List |
|---|
def first_element(lst: List[T]) -> T: |
|---|
print(first_element([1, 2, 3])) # int |
|---|
print(first_element(["a", "b"])) # str |
|---|
8️⃣ Literal(字面量类型)
from typing import Literal |
|---|
def move(direction: Literal["left", "right", "up", "down"]) -> None: |
|---|
``print(f"Moving {direction}") |
|---|
# move("forward") # ❌ IDE 会提示错误 |
|---|
9️⃣ Final & ClassVar
from typing import Final, ClassVar |
|---|
PI: Final = 3.14159 # 常量,不应被修改 |
|---|
``version: ClassVar[str] = "1.0" # 类变量 |
|---|
🔟 TypedDict(类似 JSON 的类型约束)
from typing import TypedDict |
|---|
user: User = {"id": 1, "name": "Alice", "active": True} |
|---|
1️⃣1️⃣ NewType(定义“新类型”)
from typing import NewType |
|---|
UserId = NewType("UserId", int) |
|---|
def get_user(user_id: UserId) -> str: |
|---|
``return f"User {user_id}" |
|---|
print(get_user(UserId(42))) |
|---|
1️⃣2️⃣ Self(Python 3.11+ 新增)
``def __init__(self, value: int): |
|---|
| ``self.next: Self | None = None |
| ------------------------------------------ |
🔧 类型检查工具
运行时不会检查类型,但可以用 mypy 做静态检查:
✅ 总结:
- 常用:
List / Dict / Tuple / Set
- 可选类型:
Union / Optional
- 函数:
Callable
- 泛型:
TypeVar
- 高级:
Literal / TypedDict / NewType
好嘞阿杰 👍,我给你整理一份超实用的 Python typing 最常用 20 个用法 + 真实业务场景代码。这样你在做 Web、爬虫、数据分析、API 开发时能直接套用。
🐍 Python typing 20 大常用用法 + 业务场景
1️⃣ 基本类型注解
📌 场景:API 返回值定义用户信息。
2️⃣ List(列表)
user_ids: List[int] = [1, 2, 3] |
|---|
📌 场景:数据库查询返回多个用户 ID。
3️⃣ Dict(字典)
user: Dict[str, str] = {"name": "Alice", "email": "alice@test.com"} |
|---|
📌 场景:存储用户信息。
4️⃣ Tuple(元组)
location: Tuple[float, float] = (39.9, 116.4) # (纬度, 经度) |
|---|
📌 场景:地图坐标点。
5️⃣ Set(集合)
tags: Set[str] = {"python", "ai", "nlp"} |
|---|
📌 场景:博客文章标签。
6️⃣ Union(多种可能类型)
id_or_name: Union[int, str] = "Alice" |
|---|
📌 场景:搜索接口支持用 id 或 name 查询。
7️⃣ Optional(可为空)
from typing import Optional |
|---|
middle_name: Optional[str] = None |
|---|
📌 场景:用户可能没有填写中间名。
8️⃣ Callable(函数类型)
from typing import Callable |
|---|
def run_task(task: Callable[[int], str], value: int) -> str: |
|---|
def to_str(x: int) -> str: |
|---|
print(run_task(to_str, 123)) |
|---|
📌 场景:回调函数 / 中间件。
9️⃣ Any(任意类型)
data: Any = {"key": "value"} # 可以是任何类型 |
|---|
📌 场景:第三方 API 返回值不确定。
🔟 TypeVar(泛型)
from typing import TypeVar, List |
|---|
def first_element(items: List[T]) -> T: |
|---|
print(first_element([1, 2, 3])) # int |
|---|
print(first_element(["a", "b"])) # str |
|---|
📌 场景:通用工具函数。
1️⃣1️⃣ Literal(字面量类型)
from typing import Literal |
|---|
def set_status(status: Literal["active", "inactive"]) -> None: |
|---|
``print(f"Status set to {status}") |
|---|
📌 场景:订单状态 / 枚举字段。
1️⃣2️⃣ Final(不可修改常量)
API_VERSION: Final = "v1" |
|---|
📌 场景:定义全局常量。
1️⃣3️⃣ ClassVar(类变量)
from typing import ClassVar |
|---|
``version: ClassVar[str] = "1.0" |
|---|
📌 场景:类属性,而不是实例属性。
1️⃣4️⃣ TypedDict(JSON-like 类型)
from typing import TypedDict |
|---|
user: User = {"id": 1, "name": "Alice", "active": True} |
|---|
📌 场景:接口返回 JSON 数据模型。
1️⃣5️⃣ NewType(自定义新类型)
from typing import NewType |
|---|
UserId = NewType("UserId", int) |
|---|
def get_user(user_id: UserId) -> str: |
|---|
``return f"User {user_id}" |
|---|
📌 场景:区分不同 ID(避免混用)。
1️⃣6️⃣ Generator(生成器)
from typing import Generator |
|---|
def number_stream() -> Generator[int, None, None]: |
|---|
📌 场景:流式处理大数据。
1️⃣7️⃣ Iterable / Iterator
from typing import Iterable, Iterator |
|---|
def print_items(items: Iterable[str]) -> None: |
|---|
def get_iterator() -> Iterator[int]: |
|---|
📌 场景:函数接收任意可迭代对象。
1️⃣8️⃣ Self(Python 3.11+)
``def __init__(self, value: int): |
|---|
| ``self.next: Self | None = None |
| ------------------------------------------ |
📌 场景:链表 / 树结构。
1️⃣9️⃣ Typed Callable 返回 JSON
from typing import Callable, Dict |
|---|
def fetch_api(get_json: Callable[[], Dict[str, Any]]) -> Dict[str, Any]: |
|---|
📌 场景:HTTP 请求封装。
2️⃣0️⃣ Annotated(带元信息的类型,Python 3.9+)
from typing import Annotated |
|---|
def login(username: Annotated[str, "用户名"], password: Annotated[str, "密码"]) -> bool: |
|---|
``return username == "admin" and password == "123" |
|---|
📌 场景:API 参数文档 / FastAPI 框架。
✅ 总结
- 常用基础:
List、Dict、Tuple、Set、Optional
- 函数相关:
Callable、Generator、Iterable
- 高级工具:
TypeVar、Literal、TypedDict、NewType、Annotated
- 类相关:
Final、ClassVar、Self
这样,你可以写出既直观又安全的类型注解,配合 mypy 静态检查效果更佳。
好嘞阿杰 👍,我给你写一个 小型完整项目示例:用户管理 API,全程用 typing 注解,代码风格类似 FastAPI + Python typing,涵盖你刚才想要的真实业务场景。
🐍 用户管理 API 示例(带 typing 注解)
from typing import List, Dict, Optional, TypedDict, NewType, Literal |
|---|
from typing import Union, Final |
|---|
API_VERSION: Final = "v1" |
|---|
UserId = NewType("UserId", int) |
|---|
``role: Literal["admin", "user", "guest"] # 枚举型 |
|---|
_db: Dict[UserId, User] = { |
|---|
``UserId(1): {"id": UserId(1), "name": "Alice", "email": "alice@test.com", "active": True, "role": "admin"}, |
|---|
``UserId(2): {"id": UserId(2), "name": "Bob", "email": "bob@test.com", "active": False, "role": "user"}, |
|---|
def get_user(user_id: UserId) -> Optional[User]: |
|---|
``return _db.get(user_id) |
|---|
def list_users(active_only: bool = False) -> List[User]: |
|---|
``return [u for u in _db.values() if u["active"]] |
|---|
``return list(_db.values()) |
|---|
def create_user(name: str, email: str, role: Literal["admin", "user", "guest"]) -> User: |
|---|
``new_id = UserId(max(_db.keys()) + 1 if _db else 1) |
|---|
def update_user(user_id: UserId, name: Optional[str] = None, email: Optional[str] = None) -> Optional[User]: |
|---|
``user = _db.get(user_id) |
|---|
def delete_user(user_id: UserId) -> bool: |
|---|
if __name__ == "__main__": |
|---|
``print(f"API Version: {API_VERSION}") |
|---|
``print(get_user(UserId(1))) |
|---|
``new_user = create_user("Charlie", "charlie@test.com", "guest") |
|---|
``updated_user = update_user(UserId(2), name="Bobby") |
|---|
``print(delete_user(UserId(1))) |
|---|
🔎 代码说明
- TypedDict + NewType → 定义用户数据结构,区分
UserId 和普通 int。
- Optional / Literal → 支持用户字段可选,角色有固定值。
- List / Dict → 模拟数据库存储和查询。
- Final →
API_VERSION 不允许被改动。
- 完整 CRUD 功能 →
get / list / create / update / delete。
✅ 运行效果示例
[{'id': 1, 'name': 'Alice', 'email': 'alice@test.com', 'active': True, 'role': 'admin'}, |
|---|
``{'id': 2, 'name': 'Bob', 'email': 'bob@test.com', 'active': False, 'role': 'user'}] |
|---|
{'id': 1, 'name': 'Alice', 'email': 'alice@test.com', 'active': True, 'role': 'admin'} |
|---|
{'id': 3, 'name': 'Charlie', 'email': 'charlie@test.com', 'active': True, 'role': 'guest'} |
|---|
{'id': 2, 'name': 'Bobby', 'email': 'bob@test.com', 'active': False, 'role': 'user'} |
|---|
[{'id': 2, 'name': 'Bobby', 'email': 'bob@test.com', 'active': False, 'role': 'user'}, |
|---|
``{'id': 3, 'name': 'Charlie', 'email': 'charlie@test.com', 'active': True, 'role': 'guest'}] |
|---|
👌 阿杰,我来给你一个 超详细 Python typing 模块全解析,包含常用类型、进阶用法、代码示例和最佳实践。
🐍 Python typing 模块详解
Python 的 typing 模块主要用于 类型提示(type hints) ,帮助开发者写出更规范、可读性更强的代码,同时也能借助 静态检查工具(如 mypy、pyright、Pylance) 提前发现潜在错误。
1️⃣ 基础类型注解
from typing import List, Dict, Tuple, Set, Union, Optional |
|---|
numbers: List[int] = [1, 2, 3] |
|---|
user: Dict[str, int] = {"id": 101, "score": 95} |
|---|
point: Tuple[int, int] = (10, 20) |
|---|
unique_ids: Set[str] = {"a", "b", "c"} |
|---|
# 可选值(等价于 Union[int, None]) |
|---|
maybe_num: Optional[int] = None |
|---|
2️⃣ 函数参数和返回值
def add(a: int, b: int) -> int: |
|---|
def safe_divide(a: int, b: int) -> Union[int, str]: |
|---|
``return "Error" if b == 0 else a // b |
|---|
3️⃣ 高级容器
from typing import List, Dict, Tuple |
|---|
points: List[Tuple[int, int]] = [(1, 2), (3, 4)] |
|---|
user_data: Dict[str, Dict[str, int]] = { |
|---|
``"阿杰": {"math": 90, "english": 88}, |
|---|
4️⃣ Any 和 NoReturn
from typing import Any, NoReturn |
|---|
def process(data: Any) -> None: |
|---|
def fatal_error(msg: str) -> NoReturn: |
|---|
``raise RuntimeError(msg) |
|---|
5️⃣ Callable(函数类型)
from typing import Callable |
|---|
# 接收一个函数参数(输入两个 int,返回 int) |
|---|
def operate(func: Callable[[int, int], int], x: int, y: int) -> int: |
|---|
result = operate(lambda a, b: a + b, 3, 5) # ✅ 8 |
|---|
6️⃣ TypeVar(泛型)
from typing import TypeVar, List |
|---|
def first_item(items: List[T]) -> T: |
|---|
print(first_item([1, 2, 3])) # int |
|---|
print(first_item(["a", "b", "c"])) # str |
|---|
7️⃣ Generic(泛型类)
from typing import Generic, TypeVar |
|---|
``def __init__(self, value: T): |
|---|
str_box = Box[str]("hello") |
|---|
8️⃣ Literal(字面量类型)
from typing import Literal |
|---|
def set_status(status: Literal["open", "closed", "pending"]) -> None: |
|---|
``print(f"Status: {status}") |
|---|
# set_status("error") # ❌ 静态检查报错 |
|---|
9️⃣ TypedDict(字典类型约束)
from typing import TypedDict |
|---|
u: User = {"id": 1, "name": "阿杰", "is_active": True} |
|---|
🔟 新特性(Python 3.9+ 简化写法)
list[int] # 等价于 List[int] |
|---|
dict[str, int] # 等价于 Dict[str, int] |
|---|
tuple[int, str] # 等价于 Tuple[int, str] |
|---|
✅ 总结
List, Dict, Tuple, Set, Optional, Union → 常见容器和类型组合
Callable → 函数类型
Any, NoReturn → 特殊场景
TypeVar, Generic → 泛型
Literal, TypedDict → 更严格的约束
- Python 3.9+ → 原生写法更简洁
www.52runoob.com/archives/68…