1. 项目概述Python构建天气查询MCP服务器去年在开发物联网项目时经常需要获取实时天气数据来触发设备行为。当时发现市面上的天气API要么收费昂贵要么响应缓慢于是萌生了自建轻量级天气服务的想法。这个用Python实现的MCPMicro Control Protocol服务器核心功能是通过HTTP接口返回JSON格式的天气数据特别适合嵌入式设备和自动化系统调用。相比传统Web服务MCP协议具有以下优势极简的二进制协议头仅4字节内置数据校验机制支持请求/响应模式平均延迟低于50ms2. 技术架构设计2.1 协议栈选择采用分层架构设计[TCP层] ← [MCP协议层] ← [业务逻辑层] ↑ [HTTP兼容层]关键设计决策保留MCP的高效二进制特性通过中间层支持HTTP RESTful调用使用单端口(8080)处理双协议2.2 核心组件实现class MCPServer(asyncore.dispatcher): def __init__(self, port): asyncore.dispatcher.__init__(self) self.create_socket(socket.AF_INET, socket.SOCK_STREAM) self.set_reuse_addr() self.bind((, port)) self.listen(5) def handle_accept(self): conn, addr self.accept() handler RequestHandler(conn)注意必须设置SO_REUSEADDR选项否则快速重启时会出现端口占用错误3. 天气数据获取方案3.1 数据源对接通过爬虫获取中国天气网数据使用BeautifulSoup解析def fetch_weather(city_code): url fhttp://www.weather.com.cn/weather/{city_code}.shtml headers {User-Agent: Mozilla/5.0} resp requests.get(url, headersheaders) soup BeautifulSoup(resp.text, html.parser) weather_data { temp: soup.select(.tem i)[0].text, weather: soup.select(.wea)[0].text, wind: soup.select(.win i)[0].text } return weather_data3.2 数据缓存机制使用LRU缓存策略减少请求次数from functools import lru_cache lru_cache(maxsize100) def get_cached_weather(city_code): return fetch_weather(city_code)缓存参数调优建议一线城市缓存时间60分钟二三线城市缓存时间120分钟其他地区缓存时间180分钟4. 协议转换实现4.1 MCP报文解析MCP协议帧结构0 1 2 3 4 ... ----------------------------------- | MAGIC| TYPE | LEN | CRC | DATA | -----------------------------------解析示例def parse_mcp(data): if len(data) 4: raise ValueError(Invalid MCP header) magic data[0] if magic ! 0xA5: raise ValueError(Bad magic number) payload_len data[2] crc data[3] # ...校验处理...4.2 HTTP兼容层自动识别协议类型并路由def detect_protocol(data): if data.startswith(bGET) or data.startswith(bPOST): return HTTP elif len(data) 4 and data[0] 0xA5: return MCP else: return UNKNOWN5. 性能优化技巧5.1 连接池管理使用gevent实现协程池from gevent.pool import Pool pool Pool(100) # 最大并发连接数 def handle_request(conn): try: data conn.recv(1024) protocol detect_protocol(data) # ...处理逻辑... finally: conn.close() while True: conn, addr server_socket.accept() pool.spawn(handle_request, conn)5.2 内存优化针对嵌入式环境的内存优化方案预分配固定大小缓冲区禁用Python垃圾回收器使用array代替list存储报文6. 部署实践6.1 系统服务化创建systemd服务单元[Unit] DescriptionWeather MCP Server Afternetwork.target [Service] ExecStart/usr/bin/python3 /opt/mcp_server/main.py Restartalways Userwww-data [Install] WantedBymulti-user.target6.2 容器化部署Dockerfile配置要点FROM python:3.8-slim COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt EXPOSE 8080 USER nobody CMD [python, server.py]构建命令docker build -t weather-mcp . docker run -d -p 8080:8080 --name mcp-server weather-mcp7. 常见问题排查7.1 连接拒绝问题典型错误场景防火墙未放行8080端口SELinux策略限制服务绑定到127.0.0.1检查命令netstat -tulnp | grep 8080 iptables -L -n -v getenforce7.2 性能瓶颈分析使用py-spy进行性能分析# 安装profiler pip install py-spy # 采样CPU使用情况 py-spy top --pid $(pgrep -f mcp_server) # 生成火焰图 py-spy record -o profile.svg --pid $(pgrep -f mcp_server)8. 安全加固措施8.1 输入验证防范SQL注入和命令注入def validate_city_code(code): if not isinstance(code, str): return False return re.match(r^\d{9}$, code) is not None8.2 速率限制使用令牌桶算法防CC攻击from ratelimit import limits, sleep_and_retry sleep_and_retry limits(calls100, period60) def api_handler(request): # 业务逻辑9. 客户端开发示例9.1 Python调用示例import requests def get_weather(city): url fhttp://mcp-server:8080/weather?city{city} resp requests.get(url) if resp.status_code 200: return resp.json() else: raise Exception(resp.text)9.2 C语言MCP客户端#include stdio.h #include stdlib.h #include unistd.h #include netinet/in.h struct mcp_header { uint8_t magic; uint8_t type; uint16_t len; uint16_t crc; }; void send_mcp_request(int sockfd, const char *city) { struct mcp_header hdr { .magic 0xA5, .type 0x01, .len htons(strlen(city)), .crc 0 }; // ...发送逻辑... }10. 扩展开发建议增加WebSocket支持实现实时推送集成MQTT协议适配IoT场景添加Prometheus监控指标实现集群化部署方案实际部署中发现在树莓派4B上运行该服务时单实例可稳定处理800 QPS。关键配置是调整Linux内核参数# 增加最大文件描述符 echo fs.file-max 100000 /etc/sysctl.conf # 优化TCP栈 echo net.ipv4.tcp_tw_reuse 1 /etc/sysctl.conf echo net.core.somaxconn 32768 /etc/sysctl.conf