Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[3.3] Introduce preferred-protocol for consumer and provider to automatically negotiate the protocol to consume. #14188

Merged
merged 4 commits into from
Sep 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -629,6 +629,8 @@ public interface CommonConstants {

String EXT_PROTOCOL = "ext.protocol";

String PREFERRED_PROTOCOL = "preferred.protocol";

String IS_EXTRA = "isExtra";

String ZOOKEEPER_ENSEMBLE_TRACKER_KEY = "zookeeper.ensemble.tracker";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,8 @@ public class ProtocolConfig extends AbstractConfig {
*/
private String extProtocol;

private String preferredProtocol;

/**
* JSON check level for serialization.
*/
Expand Down Expand Up @@ -629,6 +631,14 @@ public void setExtProtocol(String extProtocol) {
this.extProtocol = extProtocol;
}

public String getPreferredProtocol() {
return preferredProtocol;
}

public void setPreferredProtocol(String preferredProtocol) {
this.preferredProtocol = preferredProtocol;
}

public Boolean isNoInterfaceSupport() {
return noInterfaceSupport;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -558,7 +558,7 @@ public <T extends AbstractConfig> List<T> loadConfigsOfTypeFromProps(Class<T> cl
config.refresh();
} catch (Exception e) {
throw new IllegalStateException(
"create default config instance failed, type:" + cls.getSimpleName());
"create default config instance failed, type:" + cls.getSimpleName(), e);
}

this.addConfig(config);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1305,6 +1305,11 @@
<xsd:documentation><![CDATA[ Is SSL enabled. ]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="preferred-protocol" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[ Tell consumer the preferred protocol to consume. ]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:anyAttribute namespace="##other" processContents="lax"/>
</xsd:complexType>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1791,6 +1791,11 @@
<xsd:documentation><![CDATA[ Is SSL enabled. ]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="preferred-protocol" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[ Tell consumer the preferred protocol to consume. ]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:anyAttribute namespace="##other" processContents="lax"/>
</xsd:complexType>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
import static org.apache.dubbo.common.constants.CommonConstants.EXT_PROTOCOL;
import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.INTERFACE_REGISTER_MODE;
import static org.apache.dubbo.common.constants.CommonConstants.PREFERRED_PROTOCOL;
import static org.apache.dubbo.common.constants.CommonConstants.PROTOCOL_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.SIDE_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.VERSION_KEY;
Expand Down Expand Up @@ -508,31 +509,40 @@ private Map<URL, Invoker<T>> toInvokers(Map<URL, Invoker<T>> oldUrlInvokerMap, L
/**
* Get the protocol to consume by matching the consumer acceptable protocols and the available provider protocols.
* <p>
* Only one protocol will be used if consumer set to accept multiple protocols, for example, dubbo.consumer.protocol='tri,rest'.
* Only the first protocol that can match with the provider protocols will be used if consumer set to accept multiple protocols.
* For example, if dubbo.consumer.protocol='tri,rest' is set and provider provides tri protocol, then consumer will use tri protocol to communicate with provider.
*
* @param queryProtocols consumer side protocols.
* @param url provider url that have extra protocols specified.
* @return the protocol to consume.
*/
private String getEffectiveProtocol(String queryProtocols, URL url) {
String protocol = url.getProtocol();
String prioritizedProtocol = url.getParameter(PREFERRED_PROTOCOL, protocol);

String effectiveProtocol = prioritizedProtocol;

if (StringUtils.isNotEmpty(queryProtocols)) {
String[] acceptProtocols = queryProtocols.split(COMMA_SEPARATOR);
String acceptedProtocol = acceptProtocols[0];
if (!acceptedProtocol.equals(url.getProtocol())) {
String extProtocols = url.getParameter(EXT_PROTOCOL);
if (StringUtils.isNotEmpty(extProtocols)) {
String[] extProtocolsArr = extProtocols.split(COMMA_SEPARATOR);
for (String p : extProtocolsArr) {
if (p.equalsIgnoreCase(acceptedProtocol)) {
protocol = acceptedProtocol;
break;
if (!acceptedProtocol.equals(prioritizedProtocol)) {
if (!acceptedProtocol.equals(protocol)) {
String extProtocols = url.getParameter(EXT_PROTOCOL);
if (StringUtils.isNotEmpty(extProtocols)) {
String[] extProtocolsArr = extProtocols.split(COMMA_SEPARATOR);
for (String p : extProtocolsArr) {
if (p.equalsIgnoreCase(acceptedProtocol)) {
effectiveProtocol = acceptedProtocol;
break;
}
}
}
} else {
effectiveProtocol = protocol;
}
}
}
return protocol;
return effectiveProtocol;
}

private boolean checkProtocolValid(String queryProtocols, URL providerUrl) {
Expand Down
Loading