• Flask微服务注册到Nacos


    一、前言

    最近有一个使用 SpringCloud 的微服务项目,需要使用到 Flask 提供一些深度学习的模型接口。Java那边使用的 Nacos 作为注册中心,所以也需要把 Flask 的服务注册上去。

    本文会谈到手写实现Flask服务注册到Nacos与基于nacos-sdk-python注册,以及SpringBoot调用Flask以及SpringGateway网关请求转发调用Flask。


    二、手写实现Flask注册到Nacos

    1. 服务注册

    Nacos官方文档给出了服务注册的请求地址。
    在这里插入图片描述

    • 请求地址:
      http://127.0.0.1:8848/nacos/v1/ns/instance?serviceName=服务名&ip=服务ip地址&port=服务端口
    • 请求方式:POST

    逻辑很简单,直接给出实现

    import requests
    from flask import Flask
    
    app = Flask(__name__)
    
    # 服务注册
    def service_register():
    	url = "http://127.0.0.1:8848/nacos/v1/ns/instance?serviceName=pythonservice&ip=127.0.0.1&port=5000"
    	res = requests.post(url)
    	print("完成注册")
    
    if __name__ == '__main__':
    	service_register()
    	app.run()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    登录到Nacos的控制页面,可以看到确实已经注册上去了。

    在这里插入图片描述
    但当我们再隔一段时间后(准确来说是15秒),发现已经没有了健康实例。

    在这里插入图片描述
    再隔一段时间后(准确来说是30秒),发现已经没有了服务。

    在这里插入图片描述
    这得从Nacos对服务实例的健康检查说起。我们刚才注册上去的服务是临时实例

    • 对于临时实例
      Nacos服务端在15秒内如果没收到客户端的心跳请求,会将该实例设置为不健康,在30秒内没收到心跳,会将这个临时实例摘除。

    • 对于非临时实例
      Nacos会主动询问,也就是不再需要客户端主动完成心跳检测。

    为了保证我们的服务注册上去以后,保持健康状态,即让Nacos服务端知道我们的服务并没有问题。因此需要定期(一般是5秒)向Nacos服务端发起心跳检测的请求。

    2. 心跳检测

    • 请求地址:
      http://127.0.0.1:8848/nacos/v1/ns/instance/beat?serviceName=服务名&ip=服务ip地址&port=服务端口
    • 请求方式:PUT
    import requests
    from flask import Flask
    
    import time
    # 用于异步处理心跳检测
    import threading
    
    app = Flask(__name__)
    
    # 服务注册
    def service_register():
    	url = "http://127.0.0.1:8848/nacos/v1/ns/instance?serviceName=pythonservice&ip=127.0.0.1&port=5000"
    	res = requests.post(url)
    	print("完成注册")
    
    # 心跳检测
    def service_beat():
    	while True:
    		url = "http://127.0.0.1:8848/nacos/v1/ns/instance/beat?serviceName=pythonservice&ip=127.0.0.1&port=5000"
    		res = requests.put(url)
    		print(f"心跳检测中... 响应状态码: {res.status_code}")
    		time.sleep(5)
    
    if __name__ == '__main__':
    	service_register()
    	# 5 秒后执行心跳检测
    	threading.Timer(5, service_beat()).start()
    	app.run()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    三、使用nacos-sdk-python完成注册

    Nacos官方文档

    • 安装 nacos-sdk-python 模块
    pip install nacos-sdk-python
    
    • 1
    • 服务注册
    import nacos
    import threading
    from flask import Flask
    
    app = Flask(__name__)
    
    # nacos 服务地址
    SERVER_ADDRESSES = "http://127.0.0.1:8848"
    
    # 官方文档中更加详细的描述了此方法的形参,包括命名空间、sk、ak等
    # 在此处,我只需要传 服务地址 即可
    client = nacos.NacosClient(SERVER_ADDRESSES)
    
    def service_register():
    	"""
    	 ephemeral参数:是否是临时服务,应为false; 
    	 刚才上面也提到了,如果是 非临时实例,客户端就无需主动完成心跳检测。
    	 因此此处将服务注册为 非临时实例
    	"""
    	client.add_naming_instance("pythonservice", "127.0.0.1", "5000", ephemeral=False)
    
    if __name__ == '__main__':
    	threading.Timer(5, service_register).start()
    	app.run()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    四、SpringBoot远程调用

    我先给出Java部分的代码结构,在此处,我们只会使用到 java-demo 模块,在下面一节,就会使用到 gateway 模块。
    在这里插入图片描述

    1. 添加 Python 端业务逻辑

    在此处,我们简单的套上了一个 Flask 接口。

    @app.route("/py", methods=['get'])
    def py1():
    	print("hello py")
    	return "hello, python service"
    
    • 1
    • 2
    • 3
    • 4

    2. SpringBoot 的远程调用

    • java-demo 模块的配置如下
    server:
      port: 8081
    spring:
      application:
        name: javaservice
      cloud:
        nacos:
          server-addr: localhost:8848
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 业务逻辑如下
    @SpringBootApplication
    @RestController
    @RequestMapping("/java")
    public class JavaDemoApplication {
    
        @Autowired
        private RestTemplate restTemplate;
    
        @Bean
        @LoadBalanced
        public RestTemplate restTemplate() {
            return new RestTemplate();
        }
    
    
        public static void main(String[] args) {
            SpringApplication.run(JavaDemoApplication.class, args);
        }
    
        @GetMapping
        public String javaService(){
            System.out.println("java service start...");
            String url = "http://pythonservice/py";
            // 发送http请求,实现远程调用
            String ps = restTemplate.getForObject(url, String.class);
            System.out.println("Python service 返回内容: 【 " + ps + "】");
            return "Java远程调用Python: " + ps;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 访问接口
      在这里插入图片描述

    五、SpringGateway网关转发

    回到我最开始的初衷,我们是想提供深度学习模型的接口,因此还是希望前端直接调用Flask的接口而不是先调Java,Java再调Flask。
    而微服务中一般会使用SpringGateway来做请求转发,因此,我们就来做SpringGateway转发到我们的Flask接口。

    • gateway 模块的配置如下
    server:
      port: 10010
    spring:
      application:
        name: gateway
      cloud:
        nacos:
          server-addr: localhost:8848 
        gateway:
          routes:
            - id: javaservice 
              uri: lb://javaservice 
              predicates: 
                - Path=/java/**
            - id: pythonservice
              uri: lb://pythonservice
              predicates:
                - Path=/py/**
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    这里,我们将SpringBoot服务与Flask服务均做了请求转发配置

    • 访问接口

    在这里插入图片描述

    在这里插入图片描述

  • 相关阅读:
    PHP导入上千万CSV数据处理
    mysql同步数据到es
    Vue3:自定义图标选择器(包含 SVG 图标封装)
    HarmonyOS—低代码开发Demo示例
    软件实训-例会1
    Nextcloud fpm 版在 Dokcer 下安装踩坑
    Python和PyTorch深入实现线性回归模型:一篇文章全面掌握基础机器学习技术
    监控与升级
    本地websocket服务端暴露至公网访问【内网穿透】
    递归代码和动态规划代码相互转化
  • 原文地址:https://blog.csdn.net/qq_51938362/article/details/127914195