一、spring cloud zk注册格式
{ "name": "cloud-provider-payment", "id": "6d4e5121-6c17-4023-8f7b-8922f8b70cae", "address": "DESKTOP-26GC398", "port": 8005, "sslPort": null, "payload": { "@class": "org.springframework.cloud.zookeeper.discovery.ZookeeperInstance", "id": "application-1", "name": "cloud-provider-payment", "metadata": {} }, "registrationTimeUTC": 1610116500446, "serviceType": "DYNAMIC", "uriSpec": { "parts": [{ "value": "scheme", "variable": true }, { "value": "://", "variable": false }, { "value": "address", "variable": true }, { "value": ":", "variable": false }, { "value": "port", "variable": true } ] } }
二、zk注册bean定义
public class ServiceInstance<T> { private String name; private String id; private String address; private Integer port; private Integer sslPort; private T payload; private long registrationTimeUTC = System.currentTimeMillis(); private ServiceType serviceType = ServiceType.DYNAMIC; private UriSpec uriSpec = DEFAULT_URI_SPEC;
public static final UriSpec DEFAULT_URI_SPEC = new UriSpec("{scheme}://{address}:{port}");
}
public class ZookeeperInstance { @JsonProperty("@class") private String instanceClass = "org.springframework.cloud.zookeeper.discovery.ZookeeperInstance"; private String id; private String name; private Map<String, String> metadata = new HashMap<>(); }
public class UriSpec implements Iterable<UriSpec.Part> { private final Logger log = LoggerFactory.getLogger(getClass()); private final List<Part> parts = Lists.newArrayList(); /** * This defaults to "http". If a {@link ServiceInstance} is passed when building and an sslPort * is specified in the instance, the replacement is "https". */ public static final String FIELD_SCHEME = "scheme"; /** * If a {@link ServiceInstance} is passed when building, the replacement is {@link ServiceInstance#getName()} */ public static final String FIELD_NAME = "name"; /** * If a {@link ServiceInstance} is passed when building, the replacement is {@link ServiceInstance#getId()} */ public static final String FIELD_ID = "id"; /** * If a {@link ServiceInstance} is passed when building, the replacement is {@link ServiceInstance#getAddress()} */ public static final String FIELD_ADDRESS = "address"; /** * If a {@link ServiceInstance} is passed when building, the replacement is {@link ServiceInstance#getPort()} */ public static final String FIELD_PORT = "port"; /** * If a {@link ServiceInstance} is passed when building, the replacement is {@link ServiceInstance#getSslPort()} */ public static final String FIELD_SSL_PORT = "ssl-port"; /** * If a {@link ServiceInstance} is passed when building, the replacement is {@link ServiceInstance#getRegistrationTimeUTC()} */ public static final String FIELD_REGISTRATION_TIME_UTC = "registration-time-utc"; /** * If a {@link ServiceInstance} is passed when building, the replacement is {@link ServiceInstance#getServiceType()} */ public static final String FIELD_SERVICE_TYPE = "service-type"; /** * Always replaced with '{' - i.e. this is how to insert a literal '{' */ public static final String FIELD_OPEN_BRACE = "["; /** * Always replaced with '}' - i.e. this is how to insert a literal '}' */ public static final String FIELD_CLOSE_BRACE = "]"; /** * Represents one token in the Uri spec */ public static class Part { private final String value; private final boolean variable; /** * @param value the token value * @param isVariable if true, a replacement field. If false, a literal string */ public Part(String value, boolean isVariable) { this.value = value; this.variable = isVariable; } public Part() { value = ""; variable = false; } public String getValue() { return value; } public boolean isVariable() { return variable; } @SuppressWarnings("RedundantIfStatement") @Override public boolean equals(Object o) { if ( this == o ) { return true; } if ( o == null || getClass() != o.getClass() ) { return false; } Part part = (Part)o; if ( variable != part.variable ) { return false; } if ( !value.equals(part.value) ) { return false; } return true; } @Override public int hashCode() { int result = value.hashCode(); result = 31 * result + (variable ? 1 : 0); return result; } } public UriSpec() { // NOP } /** * @param rawSpec the spec to parse */ public UriSpec(String rawSpec) { boolean isInsideVariable = false; StringTokenizer tokenizer = new StringTokenizer(rawSpec, "{}", true); while ( tokenizer.hasMoreTokens() ) { String token = tokenizer.nextToken(); if ( token.equals("{") ) { Preconditions.checkState(!isInsideVariable, "{ is not allowed inside of a variable specification"); isInsideVariable = true; } else if ( token.equals("}") ) { Preconditions.checkState(isInsideVariable, "} must be preceded by {"); isInsideVariable = false; } else { if ( isInsideVariable ) { token = token.trim(); } add(new Part(token, isInsideVariable)); } } Preconditions.checkState(!isInsideVariable, "Final variable not closed - expected }"); } /** * Build into a UriSpec string * * @return UriSpec string */ public String build() { return build(null, Maps.<String, Object>newHashMap()); } /** * Build into a UriSpec string * * @param serviceInstance instance to use for pre-defined replacement fields * @return UriSpec string */ public String build(ServiceInstance<?> serviceInstance) { return build(serviceInstance, Maps.<String, Object>newHashMap()); } /** * Build into a UriSpec string * * @param variables a mapping of field replacement names to values. Note: any fields listed * in this map override pre-defined fields * @return UriSpec string */ public String build(Map<String, Object> variables) { return build(null, variables); } /** * Build into a UriSpec string * * @param serviceInstance instance to use for pre-defined replacement fields * @param variables a mapping of field replacement names to values. Note: any fields listed * in this map override pre-defined fields * @return UriSpec string */ public String build(ServiceInstance<?> serviceInstance, Map<String, Object> variables) { Map<String, Object> localVariables = Maps.newHashMap(); localVariables.put(FIELD_OPEN_BRACE, "{"); localVariables.put(FIELD_CLOSE_BRACE, "}"); localVariables.put(FIELD_SCHEME, "http"); if ( serviceInstance != null ) { localVariables.put(FIELD_NAME, nullCheck(serviceInstance.getName())); localVariables.put(FIELD_ID, nullCheck(serviceInstance.getId())); localVariables.put(FIELD_ADDRESS, nullCheck(serviceInstance.getAddress())); localVariables.put(FIELD_PORT, nullCheck(serviceInstance.getPort())); localVariables.put(FIELD_SSL_PORT, nullCheck(serviceInstance.getSslPort())); localVariables.put(FIELD_REGISTRATION_TIME_UTC, nullCheck(serviceInstance.getRegistrationTimeUTC())); localVariables.put(FIELD_SERVICE_TYPE, (serviceInstance.getServiceType() != null) ? serviceInstance.getServiceType().name().toLowerCase() : ""); if ( serviceInstance.getSslPort() != null ) { localVariables.put(FIELD_SCHEME, "https"); } } localVariables.putAll(variables); StringBuilder str = new StringBuilder(); for ( Part p : parts ) { if ( p.isVariable() ) { Object value = localVariables.get(p.getValue()); if ( value == null ) { log.debug("Variable not found: " + p.getValue()); } else { str.append(value); } } else { str.append(p.getValue()); } } return str.toString(); } @Override public Iterator<Part> iterator() { return Iterators.unmodifiableIterator(parts.iterator()); } /** * @return the parts */ public List<Part> getParts() { return ImmutableList.copyOf(parts); } /** * Add a part to the end of the list * * @param part part to add */ public void add(Part part) { parts.add(part); } /** * Remove the given part * * @param part the part */ public void remove(Part part) { parts.remove(part); } @SuppressWarnings("RedundantIfStatement") @Override public boolean equals(Object o) { if ( this == o ) { return true; } if ( o == null || getClass() != o.getClass() ) { return false; } UriSpec spec = (UriSpec)o; if ( !parts.equals(spec.parts) ) { return false; } return true; } @Override public int hashCode() { return parts.hashCode(); } private Object nullCheck(Object o) { return (o != null) ? o : ""; } }