In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-16 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Servers >
Share
Shulou(Shulou.com)06/02 Report--
The problem of migrating Dubbo applications to docker
Dubbo is a set of service governance and rpc framework provided by Ali. The service provider publishes its own service through zookeeper, and then the service caller obtains the ip and port of the service through zk. The dubbo client automatically selects the service provider and invokes it through its own soft load function. The tripartite relationship involved in the whole process is shown in the figure below.
Under normal circumstances, the three parties are all on the same interconnected network segment. What provider provides to zk is the local address that consumer can access.
But if the service is placed in a docker container and the caller is not in the docker, their network segments are different.
At this point, there is a problem, consumer can not access the provider.
Solutions provided by Dubbo
The new version of Dubbo provides four configurations to specify the address and port associated with the registration service.
DUBBO_IP_TO_REGISTRY: address to publish to registry DUBBO_PORT_TO_REGISTRY: Port to publish to registry DUBBO_IP_TO_BIND: service address to bind (listening address) DUBBO_PORT_TO_BIND: service port to bind
Take the IP address as an example. Dubbo first looks for whether there is a configuration of DUBBO_IP_TO_BIND. If there is an address that uses the configuration, take the local address if not. Then continue looking for DUBBO_IP_TO_REGISTRY, and if you have a configuration, use the configuration, otherwise use DUBBO_IP_TO_BIND. The specific code is as follows:
/ * Register & bind IP address for service provider, can be configured separately. * Configuration priority: environment variables-> java system properties-> host property in config file-> * / etc/hosts-> default network address-> first available network address * * @ param protocolConfig * @ param registryURLs * @ param map * @ return * / private static String findConfigedHosts (ServiceConfig sc, ProtocolConfig protocolConfig List registryURLs, Map map) {boolean anyhost = false String hostToBind = getValueFromConfig (protocolConfig, DUBBO_IP_TO_BIND); if (hostToBind! = null & & hostToBind.length () > 0 & & isInvalidLocalHost (hostToBind)) {throw new IllegalArgumentException ("Specified invalid bind ip from property:" + DUBBO_IP_TO_BIND + ", value:" + hostToBind) } / / if bind ip is not found in environment, keep looking up if (StringUtils.isEmpty (hostToBind)) {hostToBind = protocolConfig.getHost (); if (sc.getProvider ()! = null & & StringUtils.isEmpty (hostToBind)) {hostToBind = sc.getProvider () .getHost () } if (isInvalidLocalHost (hostToBind)) {anyhost = true; try {logger.info ("No valid ip found from environment, try to find valid host from DNS."); hostToBind = InetAddress.getLocalHost () .getHostAddress () } catch (UnknownHostException e) {logger.warn (e.getMessage (), e) } if (isInvalidLocalHost (hostToBind)) {if (CollectionUtils.isNotEmpty (registryURLs)) {for (URL registryURL: registryURLs) {if (MULTICAST.equalsIgnoreCase (registryURL.getParameter ("registry") { / / skip multicast registry since we cannot connect to it via Socket continue } try (Socket socket = new Socket ()) {SocketAddress addr = new InetSocketAddress (registryURL.getHost (), registryURL.getPort ()); socket.connect (addr, 1000) HostToBind = socket.getLocalAddress () .getHostAddress (); break;} catch (Exception e) {logger.warn (e.getMessage (), e) }} if (isInvalidLocalHost (hostToBind)) {hostToBind = getLocalHost () } map.put (BIND_IP_KEY, hostToBind); / / registry ip is not used for bind ip by default String hostToRegistry = getValueFromConfig (protocolConfig, DUBBO_IP_TO_REGISTRY) If (hostToRegistry! = null & & hostToRegistry.length () > 0 & & isInvalidLocalHost (hostToRegistry)) {throw new IllegalArgumentException ("Specified invalid registry ip from property:" + DUBBO_IP_TO_REGISTRY + ", value:" + hostToRegistry);} else if (StringUtils.isEmpty (hostToRegistry)) {/ / bind ip is used as registry ip by default hostToRegistry = hostToBind } map.put (ANYHOST_KEY, String.valueOf (anyhost)); return hostToRegistry;}
Then we look at this getValueFromConfig (), which calls the following function, and you can see that it looks for the environment variable first, and then properties.
Public static String getSystemProperty (String key) {String value = System.getenv (key); if (StringUtils.isEmpty (value)) {value = System.getProperty (key);} return value;}
So we can change the address and port that Dubbo publishes to zookeeper through the environment variable. If we start a dubbo provider through the docker image, and its service port is 8888, assuming the host address is 192.168.1.10, then we use the following command
Docker run-e DUBBO_IP_TO_REGISTRY=192.168.1.10-e DUBBO_PORT_TO_REGISTRY=8888-p 8888 DUBBO_PORT_TO_REGISTRY=8888 8888 dubbo_image
It allows internal services to be published at the address of 192.168.1.10 Suzhou 8888.
Let's demonstrate it through an official example, because the official cases have been provided for a long time, so I have created a new example myself, the code is in https://github.com/XinliNiu/dubbo-docker-sample.git.
Start a zookeeper first and expose port 2181.
Docker run-- name zkserver-- rm-p 2181-d zookeeper:3.4.9
Take a look. Zk is up.
Niuxinli@niuxinli-B450M-DS3H:~/dubbo-samples-docker$ docker psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES5efc1f17fba0 zookeeper:3.4.9 "/ docker-entrypoint." 4 seconds ago Up 2 seconds 2888/tcp, 3888/tcp, 0.0.0.0 3888/tcp 2181-> 2181/tcp zkserver
Import the code into IDE, modify dubbo-docker-provide.xml, and change the address to the address and port just published to zk. My address is 192.168.1.8.
Run DubboApplication, and you can see that the service is registered on zk.
Modify the zk address in dubbo-docker-consumer.xml, perform unit test, and access it normally.
Export DubboApplication to an executable jar package, named app.jar, and create the following Dockerfile
FROM openjdk:8-jdk-alpineADD app.jar app.jarENV JAVA_OPTS= "" ENTRYPOINT exec java $JAVA_OPTS-jar / app.jar
Create a dubbo-demo image and execute docker build in the same directory.
Docker build-no-cache-t dubbo-demo.
Start the mirror normally
Docker run-p 20880 rm dubbo-demo 20880 it
Found to be 172.16.0.3 address, this is not accessible.
Reboot with incoming environment variables
Docker run-e DUBBO_IP_TO_REGISTRY=192.168.1.8-e DUBBO_PORT_TO_REGISTRY=20880-p 20880 it-- rm dubbo-demo
That's when it becomes the host address.
Using Dubbo in Kubernetes
When starting multiple copies in Kubernetes, it is not feasible to specify a specific IP and a specific port, because each machine has a different IP and cannot write many yaml files, and once a specific port is specified, the port of this host is occupied.
We can fix the port by creating a Service and using NodePort, so that the port problem is solved. Because it is an external service, it is definitely not possible to use ClusterIP. There are two solutions to IP:
(1) use the downward api of Kubernetes to dynamically pass in the ip of the host.
(2) pass a fixed loadbalancer address, for example, there is an F5 outside all node.
Either way, it's a compromise, and it's not "cloud native." I'll show you how to use downward api to dynamically pass in host addresses and use nodeport fixed ports.
My kubernetes cluster is as follows:
Role address master192.168.174.50node1192.168.174.51node2192.168.174.52node3192.168.174.53
The address of zk is 192.168.1.8, and it interconnects with the hosts in the cluster.
I didn't build a private image warehouse, so I push the dubbo-demo I typed directly to docker-hub. The name is nxlhero/dubbo-demo.
Create a Service, using a NodePort of 30001, and create four copies, so that there are exactly one and two pod on the three machines.
ApiVersion: v1kind: Servicemetadata: name: dubbo-docker labels: run: dubbospec: type:-port: 20880 targetPort: 20880 nodePort: 30001 selector: run: dubbo-docker---apiVersion: apps/v1kind: Deploymentmetadata: name: dubbo-dockerspec: selector: matchLabels: run: dubbo replicas: 4 template: metadata: labels: run: dubbospec: containers:-name: dubbo-docker Image: nxlhero/dubbo-demo env:-name: DUBBO_IP_TO_REGISTRY valueFrom: fieldRef: fieldPath: status.hostIP-name: DUBBO_PORT_TO_REGISTRY value: "30001" tty: true ports:-containerPort: 20880
The most critical part of this yaml is the environment variable, where the host IP is passed in through downward apid, and the port uses a fixed nodeport.
Env:-name: DUBBO_IP_TO_REGISTRY valueFrom: fieldRef: fieldPath: status.hostIP-name: DUBBO_PORT_TO_REGISTRY value: "30001"
Create a Service, and after startup, you can see that the address on the zookeeper is the address of the host and nodeport.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.