• spring cloud kubernetes踩坑:Null key for a Map not allowed in JSON


    这里是weihubeats,觉得文章不错可以关注公众号小奏技术,文章首发。拒绝营销号,拒绝标题党

    背景

    最近在做spring cloud kubernetes改造调研,然后在获取服务元数据的时候遇到了这个错误
    Null key for a Map not allowed in JSON

    项目搭建还原

    项目依赖版本

    • spring cloud: 2021.0.4
    • spring cloud kubernetes:spring-cloud-starter-kubernetes-client: 2.1.4

    由上面spring cloud 版本管理统一管理,都是最新版本

    代码

    1. 先在Application 添加注解@EnableDiscoveryClient开启分布式客户端
    @SpringBootApplication
    @EnableDiscoveryClient
    public class Application {
    
        public static void main(String[] args) {
            SpringApplication.run(Application.class, args);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    1. 编写代码获取服务相关元数据信息
    @RestController
    @RequestMapping("/service/v1")
    @RequiredArgsConstructor
    public class ServiceController {
    
    	private final DiscoveryClient discoveryClient;
    
    	@GetMapping("/service")
    	public List<String> getServiceList(){
    		return discoveryClient.getServices();
    	}
    
    	@GetMapping("/instance")
    	public Object getInstance(String name){
    		List<ServiceInstance> instances = discoveryClient.getInstances(name);
    		return instances;
    	}
    	
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    测试

    然后将项目部署到k8s集群中,调用上面的接口

    1. 获取服务

    调用接口

    http://k8s/service/v1/service
    
    • 1

    这里天自己的k8s域名

    然后回发现可以正常返回服务列表

    2. 获取服务元数据

    我们在调通接口获取服务元数据的时候就出现了上面的报错

    http://k8s/service/v1/instance?name=test-service
    
    • 1

    Null key for a Map not allowed in JSON

    问题定位

    然后在spring-cloud-kubernetes 中找到了类似的问题

    issues链接

    大致的意思是我们在service.yaml中没有定义port的名字导致报错了。
    比如原先service.yaml的是

    apiVersion: v1
    kind: Service
    metadata:
      name: my-service
    spec:
      selector:
        app.kubernetes.io/name: MyApp
      ports:
        - protocol: TCP
          port: 80
          targetPort: 9376
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    可以看到我们没有定义port的名字所以我们可能需要加一下port的名字

    apiVersion: v1
    kind: Service
    metadata:
      name: my-service
    spec:
      selector:
        app.kubernetes.io/name: MyApp
      ports:
        - protocol: TCP
          port: 80
          name: default-http
          targetPort: 9376
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    name: default-http

    这样就解决了这个bug,那么我其他所有没有定义port name的项目呢,不是都会报错?
    所以这里其实是一个bug

    源码分析

    可以看到这里在获取port name的时候没有默认值处理,所以spring cloud kubernetes 官方维护人员也说这是一个bug,并修复了他

    代码是修复了,遗憾的好像还没有发版,中央仓库最新版本还是有这个bug

    本地自我修复

    比较好的解决方式就是在本地建立一个同包同类名的类,然后自己去修改源码

  • 相关阅读:
    JAVA设计模式之模板方法模式
    SpringMVC请求、响应与异步请求
    14:00面试,14:06就出来了,问的问题有点变态。。。
    【数据结构】什么是堆,如何使用无序数组生成一个堆?
    java webservice超时时间设置方法
    Linux (五)- mv 命令
    【快乐离散数学】Discrete Structure 课程计划书
    SSM - Springboot - MyBatis-Plus 全栈体系(二十八)
    【多线程与高并发】- synchronized锁的认知
    毫米波雷达2-雷达的工作模式
  • 原文地址:https://blog.csdn.net/qq_42651904/article/details/127578326