前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >通过 Python+Nacos实现微服务,细解微服务架构

通过 Python+Nacos实现微服务,细解微服务架构

原创
作者头像
shigen
发布于 2024-06-10 02:08:30
发布于 2024-06-10 02:08:30
1.1K0
举报

shigen坚持更新文章的博客写手,擅长Java、python、vue、shell等编程语言和各种应用程序、脚本的开发。记录成长,分享认知,留住感动。 个人IP:shigen

背景

一直以来的想法比较多,然后就用Python编写各种代码脚本。很多的脚本都是通过Python的Flask框架实现,如[file-server],然后部署到云服务器。但是这样只提供一个端口就可以通过http访问,无异于在互联网上裸奔。而且这样的服务有很多个,一直在想如何实现一个统一认证然后就可以访问这么多的服务。在Java领域最常见的设计就是使用微服务架构,把每个服务拆分出来,然后通过网关统一拦截、验证、分发流量。蹭了一张架构图(发现飞书的模板已经很好了):

微服务架构设计
微服务架构设计

那我的Python服务为什么不能设计成微服务架构呢,当然,还没听说过谁家的Python服务是微服务架构的,姑且一试。

代码实现

考虑到大家的技术栈就是Java,以下的python代码将省略部分细节。

有了之前python flask如何注册到nacos踩坑的经验,这次明显顺利的多了。现在本地搭建nacos环境,并支持http访问,推荐docker-compose的方式搭建:shigen/spring-cloud-platform

因为我的Nacos版本是2.0+的,官方的nacos-sdk-python是这样描述的:

Supported Python version:

Python 2.7 Python 3.6 Python 3.7

Supported Nacos version

Nacos 0.8.0 ~ 1.3.2

于是就使用的是官方的APIOpen API 指南

我的服务模块是这样细分的:

代码语言:JSON
AI代码解释
复制
microservices-demo/
├── nacos/
├── api-gateway/
│   └── app.py
├── user-service/
│   └── app.py
├── auth-service/
│   └── app.py
└── document-service/
    └── app.py

也就是分成了四个模块:网关、用户中心、鉴权中心、文档中心。接下来就是服务的注册和调用。我们以最简单的auth-service为例:

代码语言:Python
AI代码解释
复制
NACOS_URL = os.getenv(
    "NACOS_URL", "http://localhost:8848/nacos/v1/ns/instance")
SERVICE_NAME = "auth-service"
SERVICE_IP = socket.gethostbyname(socket.gethostname())
SERVICE_PORT = 5002
NAMESPACE = "python"

# 发送到Nacos服务注册接口
def register_service():
    payload = {
        "serviceName": SERVICE_NAME,
        "ip": SERVICE_IP,
        "port": SERVICE_PORT,
        "namespaceId": NAMESPACE,
    }
    response = requests.post(f"{NACOS_URL}", params=payload)

# 每5秒发送一次心跳
def send_heartbeat():
    while True:
        payload = {
            "serviceName": SERVICE_NAME,
            "ip": SERVICE_IP,
            "port": SERVICE_PORT,
            "namespaceId": NAMESPACE,
        }
        response = requests.put(f"{NACOS_URL}/beat", params=payload)
        time.sleep(5)

# 密码验证,获得token
@app.route('/auth', methods=['POST'])
def authenticate():
    pass

# 验证token
@app.route('/verify', methods=['POST'])
def verify_token():
    pass

# 服务启动类
if __name__ == '__main__':
    register_service()
    heartbeat_thread = threading.Thread(target=send_heartbeat)
    heartbeat_thread.daemon = True
    heartbeat_thread.start()
    app.run(port=SERVICE_PORT)

不用尝试读懂代码,很简单:在服务启动的时候注册到nacos,完了就是定时的向nacos发送心跳。@app.route('/auth', methods='POST')表示提供一个POST请求方式的/auth接口,然后启动服务:

服务启动
服务启动

服务启动成功之后,可以看到控制台打印的日志信息。同时提供http访问接口。测试的方式如下:

代码语言:Python
AI代码解释
复制
curl --location 'http://127.0.0.1:5002/auth' \
--header 'Content-Type: application/json' \
--data '{
    "username": "user",
    "password": "pass"
}'

其他的几个服务也如法炮制。最终Nacos服务注册表如下:

在网关这一块可能稍微有一点区别,复习前面提到的网关的作用:流量的拦截和转发、认证拦截、负载均衡......这里我的网关服务设计如下:

代码语言:Python
AI代码解释
复制
NACOS_URL = os.getenv(
    "NACOS_URL", "http://localhost:8848/nacos/v1/ns/instance")
NAMESPACE = "python"


def get_service_url(service_name):
    try:
        response = requests.get(
            f"{NACOS_URL}/list?serviceName={service_name}&namespaceId={NAMESPACE}")
        data = response.json()
        if data and data['hosts']:
            service = data['hosts'][0]
            # return f"http://{service['ip']}:{service['port']}"
            # 这里是本机调用测试
            return f"http://localhost:{service['port']}"
    except Exception as e:
        print(f"Error getting service URL: {e}")
    return None


@app.route('/<service_name>/<path:path>', methods=['GET', 'POST', 'PUT', 'DELETE'])
def proxy(service_name, path):
    service_url = get_service_url(service_name)
    if not service_url:
        return jsonify({"error": "Service not found"}), 404

    # 认证逻辑
    if service_name != "auth-service":
        token = request.headers.get("Authorization")
        if not token:
            return jsonify({"error": "Missing token"}), 401

        auth_url = get_service_url("auth-service")
        if not auth_url:
            return jsonify({"error": "Auth service not found"}), 500

        verify_response = requests.post(
            f"{auth_url}/verify", json={"token": token})
        if verify_response.status_code != 200:
            return jsonify({"error": "Invalid token"}), 401

    url = f"{service_url}/{path}"
    response = requests.request(
        method=request.method,
        url=url,
        headers={key: value for key,
                 value in request.headers if key != 'Host'},
        data=request.get_data(),
        cookies=request.cookies,
        allow_redirects=False
    )

    return (response.content, response.status_code, response.headers.items())


if __name__ == '__main__':
    app.run(port=8080)

这里其实就是请求来了之后,从nacos上拉取服务列表。这个服务列表就是服务名称和对应的服务所在机器的IP(service-name和对应的IP集合)。然后选取对应服务所在的机器之一作为目标机器(这里选用的是第一台机器),从请求头中获得token,进行验证和调用。token校验失败则打给认证服务,重新进行登录验证。为此,我还对比了一下Spring Cloud + Nacos的设计:

Nacos的API实现的是springframework.cloud.client.discovery的接口,意味着统一的标准:

代码语言:Java
AI代码解释
复制
package com.alibaba.cloud.nacos.discovery;

public class NacosDiscoveryClient implements DiscoveryClient {

        private static final Logger log = LoggerFactory.getLogger(NacosDiscoveryClient.class);

        /**
         * Nacos Discovery Client Description.
         */
        public static final String DESCRIPTION = "Spring Cloud Nacos Discovery Client";

        private NacosServiceDiscovery serviceDiscovery;

        public NacosDiscoveryClient(NacosServiceDiscovery nacosServiceDiscovery) {
                this.serviceDiscovery = nacosServiceDiscovery;
        }

        @Override
        public String description() {
                return DESCRIPTION;
        }

        @Override
        public List<ServiceInstance> getInstances(String serviceId) {
                try {
                        return serviceDiscovery.getInstances(serviceId);
                }
                catch (Exception e) {
                        throw new RuntimeException(
                                        "Can not get hosts from nacos server. serviceId: " + serviceId, e);
                }
        }

        @Override
        public List<String> getServices() {
                try {
                        return serviceDiscovery.getServices();
                }
                catch (Exception e) {
                        log.error("get service name from nacos server fail,", e);
                        return Collections.emptyList();
                }
        }

}

其中的serviceName和serviceId其实是同一概念,意味着我们可以通过服务名获得全部的部署服务的实例信息,实现自定义的负载均衡调用。这里的原理和我直接从Nacos的API中获得服务列表,默认选取第一台机器进行调用的设计如出一辙。

对于以上的Python代码段,可能文字描述有不详细或者不当之处,借助魔法进行进一步的完善:

这段代码实现了一个反向代理服务器,其主要功能是根据服务名称将请求转发到不同的服务,并在转发前进行认证。具体功能如下:

服务发现:代码通过访问 NACOS(一个服务发现和配置管理平台)来获取目标服务的 URL。NACOS 提供了服务注册和发现的功能,代码中通过 get_service_url(service_name) 函数实现这一功能。 请求转发:当接收到一个请求时,根据 URL 中的 service_name 和 path,代码会将请求转发到相应的目标服务。转发时,保留了原始请求的 HTTP 方法、头信息、数据和 cookies。 认证检查:对于非 auth-service 的请求,代码会检查请求头中是否包含 Authorization token。如果没有 token 或 token 无效,则会返回错误响应。具体步骤如下:检查请求头中是否包含 Authorization token。 如果没有 token,返回 401 错误(未授权)。 如果有 token,向认证服务(auth-service)发送请求,验证 token 的有效性。 如果 token 无效,返回 401 错误。 错误处理:代码包含了基本的错误处理逻辑,例如当服务 URL 无法获取或认证服务不可用时,返回相应的错误响应。

通过这些功能,该反向代理服务器能够在微服务架构中充当中间层,路由请求并提供统一的认证机制。

这样下来,我们调用服务只需要直接走网关了,其它的服务端口也不用放行,极大程度上保证了数据的安全。此时,我们需要这样调用服务:

登录

代码语言:Python
AI代码解释
复制
curl --location 'http://127.0.0.1:8080/auth-service/auth' \
--header 'Content-Type: application/json' \
--data '{
"username": "user",
"password": "pass"
}'

服务调用

代码语言:Python
AI代码解释
复制
curl --location 'http://127.0.0.1:8080/document-service/documents' \
--header 'Authorization: xxx'

总结

之前微服务的开发中,可能我们借助Spring Cloud部分组件、Nacos,在项目中加上依赖配置,稍微改一下配置文件,服务就可以正常的调用了。其中依赖的SDK如何的工作,可能只是停留在理论上,缺少实操。这次的这个案例很好的展示Python+Nacos如何实现微服务,并从中细解微服务结构和服务之间的调用原理。是不是觉得Nacos其实也不过如此哈,没什么牛掰、独特之处,其实都是草台班子。

与shigen一起,每天不一样!

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
如何使用 Nacos 对 Python 服务进行服务发现与注册
在微服务架构中,服务发现与注册是实现服务间通信的关键环节。Nacos 作为一款强大的服务发现与配置管理工具,提供了简单易用的接口来支持 Python 服务的注册与发现。以下将详细介绍如何在 Python 项目中使用 Nacos 实现服务的注册与发现。
全干程序员demo
2025/04/28
2820
如何使用 Nacos 对 Python 服务进行服务发现与注册
深入解析微服务架构设计原则【从理论到实践】
微服务架构是一种将单一应用程序拆分成一组小型服务的设计方法,每个服务运行在自己的进程中,并通过轻量级机制(通常是 HTTP 资源 API)进行通信。这种架构可以提高系统的灵活性、可扩展性和可维护性。本文将深入探讨微服务架构的设计原则,并通过代码实例展示这些原则的具体应用。
一键难忘
2024/08/03
3920
微服务架构设计-原则与实践详解
微服务架构是一种将单一应用程序拆分成一组小型服务的设计方法,每个服务运行在自己的进程中,并通过轻量级机制(通常是 HTTP 资源 API)进行通信。这种架构可以提高系统的灵活性、可扩展性和可维护性。本文将深入探讨微服务架构的设计原则,并通过代码实例展示这些原则的具体应用。
一键难忘
2024/10/06
3450
python flask服务如何注册到nacos
shigen之前遇到了一个服务,需要结合nacos+ Spring security实现服务的负载均衡。其中最为重要的就是python服务自己注册到nacos上,趁着闲暇时间,来研究了一番。
shigen
2024/03/14
5560
python flask服务如何注册到nacos
Python版本Nacos客户端
Nacos(Naming and Configuration Service)是阿里巴巴开源的一款动态服务发现、配置管理和服务管理平台。它主要用于解决微服务架构中服务发现和配置管理的问题,提供了一站式解决方案。以下是 Nacos 的几个关键功能:
CoderJia
2024/10/18
2390
Python版本Nacos客户端
使用Python进行异步微服务架构的设计与实现
微服务架构已经成为现代软件开发中的主流趋势,它将一个大型应用程序拆分为一系列小型、独立的服务,每个服务都有自己的特定功能。而异步微服务架构则更进一步,通过异步通信方式提高了系统的性能和可扩展性。本文将介绍如何使用Python构建异步微服务架构,并提供代码实例进行演示。
一键难忘
2024/07/31
2.2K0
微服务上下线动态感知实现的技术解析
文章链接:https://cloud.tencent.com/developer/article/2180464
小马哥学JAVA
2024/11/27
1520
微服务架构 CI/CD 实战
在项目根路径下执行,Maven 命令 mvn clean install -pl com.lab:book-common -am -Ptest,截取输出如下
JAVA日知录
2020/06/04
6300
微服务架构 CI/CD 实战
微服务架构:由浅入深带你了解底层注册中心
文章链接:https://cloud.tencent.com/developer/article/2465228
努力的小雨
2024/11/13
2.8K0
构建高可用微服务架构:APISIX 网关与 K3S 集群的集成方案
随着微服务架构的日益流行,企业正面临着构建高可用、可扩展且安全的微服务系统的挑战。在这种背景下,本方案提出了一种基于 APISIX 网关和 K3S 集群的微服务部署策略。这种策略不仅提高了系统的可用性和伸缩性,还简化了服务的发现和路由管理。
行者深蓝
2024/03/18
7210
Nacos 服务注册原理分析
服务是如何注册到注册中心,服务如果挂了,服务是如何检测?带着这些问题,我们从源码上对服务注册进行简单的源码分析。
用户10384376
2023/02/26
5530
Nacos 服务注册原理分析
微服务:剖析一下源码,Nacos的健康检查竟如此简单
前面我们多次提到Nacos的健康检查,比如《微服务之:服务挂的太干脆,Nacos还没反应过来,怎么办?》一文中还对健康检查进行了自定义调优。那么,Nacos的健康检查和心跳机制到底是如何实现的呢?在项目实践中是否又可以参考Nacos的健康检查机制,运用于其他地方呢?
程序新视界
2021/12/07
1.5K0
Python中的容器化与微服务架构:从Docker到服务发现与负载均衡
在现代软件开发中,容器化和微服务架构已经成为主流。容器化技术使得应用程序可以在任何环境中一致运行,而微服务架构通过将应用拆分成多个独立的服务,从而提升了系统的可扩展性和维护性。本文将介绍如何在Python中实践容器化和微服务架构,并提供相关代码实例。
一键难忘
2024/09/15
2390
解锁高性能!Webman框架驱动下的Nacos微服务注册与发现实践
服务注册与发现是微服务架构中的核心概念,它可以使服务提供者和消费者能相互发现和交互。
Tinywan
2023/10/31
7060
解锁高性能!Webman框架驱动下的Nacos微服务注册与发现实践
微服务SpringCloudday1 认识微服务与服务注册(Eureka与nacos)
随着互联网行业的发展,对服务的要求也越来越高,服务架构也从单体架构逐渐演变为现在流行的微服务架构。这些架构之间有怎样的差别呢?
小小程序员
2023/07/01
2970
微服务SpringCloudday1 认识微服务与服务注册(Eureka与nacos)
Nacos 3.0 AI云架构在PHP高性能WebMan框架动态配置最佳实践
Nacos 致力于帮助您发现、配置和管理微服务;是微服务/SOA架构体系中服务治理环节的重要成员服务;简单的可以把Nacos理解为一个配置中心和一个服务注册中心。
Tinywan
2025/06/08
1060
Nacos 3.0 AI云架构在PHP高性能WebMan框架动态配置最佳实践
微服务实现 - Netflix技术栈
你好。今天我将讨论并解释如何实现基于微服务的系统。有很多用于实现微服务的工具和技术。我今天关注的是Netflix技术栈和SpringBoot。目前微服务是业内热门话题之一。每个人都需要了解微服务,每个人都需要在微服务体系结构上完成项目。
杜逸先
2018/06/25
9930
微服务实现 - Netflix技术栈
微服务架构SpringCloud
努力,不是为了要感动谁,也不是要做给某些人看,而是有能力跳出自己厌恶的圈子,并拥有自己选择的权力,用自己喜欢的方式,过一生。
凹谷
2020/04/11
7020
微服务网关方案:Kong & Nacos
文章连接:https://mp.weixin.qq.com/s/Kk6Cl7n0sFGgCyyZtExa6A
程序员架构进阶
2021/04/14
2.1K0
微服务网关方案:Kong & Nacos
微服务系列(二)-nacos服务发现
目前市面上用的比较多的服务发现中心有:Nacos、Eureka、Consul和Zookeeper。
许喜朝
2021/01/07
1.2K0
微服务系列(二)-nacos服务发现
推荐阅读
相关推荐
如何使用 Nacos 对 Python 服务进行服务发现与注册
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档