Nacos指南-服务发现:创建服务

API

请求类型

POST

请求路径

/nacos/v1/ns/service

请求参数

名称类型是否必选描述
serviceName字符串服务名
groupName字符串分组名
namespaceId字符串命名空间ID
protectThreshold浮点数保护阈值,取值0到1,默认0
metadata字符串元数据
selectorJSON格式字符串访问策略

错误编码

错误代码描述语义
400Bad Request客户端请求中的语法错误
403Forbidden没有权限
404Not Found无法找到资源
500Internal Server Error服务器内部错误
200OK正常

示例请求

curl -X POST '127.0.0.1:8848/nacos/v1/ns/service?serviceName=nacos.test.2&metadata=k1%3dv1'

示例返回

ok

关键流程源码解析

ServiceController

    /**
     * Create a new service.
     * 新建一个服务
     * @param namespaceId      namespace id
     * @param serviceName      service name
     * @param protectThreshold protect threshold
     * @param metadata         service metadata
     * @param selector         selector
     * @return 'ok' if success
     * @throws Exception exception
     */
    @PostMapping
    @Secured(parser = NamingResourceParser.class, action = ActionTypes.WRITE)
    public String create(@RequestParam(defaultValue = Constants.DEFAULT_NAMESPACE_ID) String namespaceId,
            @RequestParam String serviceName, @RequestParam(required = false, defaultValue = "0.0F") float protectThreshold,
            @RequestParam(defaultValue = StringUtils.EMPTY) String metadata,
            @RequestParam(defaultValue = StringUtils.EMPTY) String selector) throws Exception {
        //检测是服务是否已创建
        if (serviceManager.getService(namespaceId, serviceName) != null) {
            throw new IllegalArgumentException("specified service already exists, serviceName : " + serviceName);
        }

        Map<String, String> metadataMap = new HashMap<>(16);
        if (StringUtils.isNotBlank(metadata)) {
            metadataMap = UtilsAndCommons.parseMetadata(metadata);
        }

        Service service = new Service(serviceName);
        service.setProtectThreshold(protectThreshold);
        service.setEnabled(true);
        service.setMetadata(metadataMap);
        //设置服务路由类型,默认为None,
		//可以选择标签,并设置匹配规则  格式为:{"type": "label","expression": "CONSUMER.label.myLabel=PROVIDER.label.myLabel"}
        service.setSelector(parseSelector(selector));
        service.setNamespaceId(namespaceId);
        service.setLastModifiedMillis(System.currentTimeMillis());
        service.recalculateChecksum();
        //服务名称以及集群规范性检查
        service.validate();
        //更新服务信息
        serviceManager.addOrReplaceService(service);

        return "ok";
    }
    private Selector parseSelector(String selectorJsonString) throws Exception {
        //若传入的字符串为空,返回默认类型
        if (StringUtils.isBlank(selectorJsonString)) {
            return new NoneSelector();
        }
        //{type: "label", expression: "CONSUMER.label.site=PROVIDER.label.site"}
        JsonNode selectorJson = JacksonUtils.toObj(URLDecoder.decode(selectorJsonString, "UTF-8"));
        switch (SelectorType.valueOf(selectorJson.get("type").asText())) {
            case none:
                return new NoneSelector();
            case label:
                String expression = selectorJson.get("expression").asText();
				//转化表达式标签,必须以CONSUMER.label.形式开始
                Set<String> labels = LabelSelector.parseExpression(expression);
                LabelSelector labelSelector = new LabelSelector();
                labelSelector.setExpression(expression);
                labelSelector.setLabels(labels);
                return labelSelector;
            default:
                throw new NacosException(NacosException.INVALID_PARAM, "not match any type of selector!");
        }
    }

总结

创建服务需要留意的地方就是服务路由类型可以选择标签模式,当选择标签时表达式必须以 CONSUMER.label. 开头,实际的标签可以自定义。可以结合自己公司的CMDB资源管理在查询实例列表时可以获取与表达式匹配的机房节点,该策略Nacos本身并没有实现,需要用户自己实现CmdbService配置匹配规则。具体实现此处不做描述。后续会专门写一篇案例实现。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值