BUS components
1.
Spring Cloud Bus uses a lightweight message broker to connect the nodes of a distributed system. It can then be used to broadcast state changes (such as configuration changes) or other administrative instructions. AMQP (RabbitMQ) and Kafka Broker implementations are included in the project. Alternatively, any Spring Cloud Stream binder found on the classpath can be used as a transport.
Definition 2.
The reason why Bus is called as the message Bus in Spring Cloud is mainly used to inform all clients to refresh configuration information through broadcast when remote configuration updates are implemented in microservice system, avoiding manual service restart.
Configuring Semi-automatic Refresh
1. Set up the RabbitMQ service
-
Download Erlang: www.erlang.org/downloads
-
Download RabbitMQ: github.com/rabbitmq/ra…
-
Prepare a CentOS7 vm.
-
Set up FTP and upload the two installation packages to the VM.
-
Install Erlang
The RPM - the ivh Erlang 21.3.8.6-1. El7. X86_64-2. RPMCopy the code
-
Install the RabbitMQ
Yum install -- y the rabbitmq server - 3.7.18-1. El7. Noarch. RPMCopy the code
-
The RabbitMQ after the installation is complete to/usr/share/doc/the RabbitMQ server – 3.7.18 / RabbitMQ. Config. The example configuration file to the/etc/RabbitMQ/directory, and named the RabbitMQ. Config.
Cp/usr/share/doc/the rabbitmq server - 3.7.18 / rabbitmq config. The example/etc/rabbitmq/rabbitmq configCopy the code
-
Modify rabbitmq.config
vim /etc/rabbitmq/rabbitmq.config Copy the code
-
Execute plug-in management services
rabbitmq-plugins enable rabbitmq_management Copy the code
-
Start the RabbitMQ
# start the RabbitMQ systemctl start rabbitmq-server # to restart the RabbitMQ systemctl restart rabbitmq-server # stop the RabbitMQ systemctl stop rabbitmq-server Copy the code
-
Check the RabbitMQ status
systemctl status rabbitmq-server Copy the code
-
Visit the RabbitMQ
http://VM IP address :15672/Copy the code
-
Log in to RabbitMQ using the guest account and password
Note:
-
RabbitMQ requires the Erlang environment to operate, and RabbitMQ and Erlang versions must be strictly compatible.
-
Network connection is required to install RabbitMQ because yum will need network connection to download other dependencies during RabbitMQ installation.
-
If you cannot find the correct location to change rabbitmq.config, enter “:61” to go to line 61 and remove the first two %’s and the last comma.
-
If http://VM IP address :15672/ cannot access the RabbitMQ page, enable the VM port or disable the firewall on the VM.
Open VM ports (recommended) :
# Open vm ports sudo firewall-cmd --permanent --add-port=15672/tcp sudo firewall-cmd --permanent --add-port=5672/tcp # Disable the vm port sudo firewall-cmd --permanent --remove-port=15672/tcp sudo firewall-cmd --permanent --remove-port=5672/tcp You need to restart the firewall after entering the open and close commands firewall-cmd --reload Copy the code
Disable the firewall:
systemctl disable firewalld systemctl stop firewalld Check the firewall status systemctl status firewalld Copy the code
2. Automatically refresh the configuration
In this case, automatic refreshing is implemented on the basis of manual refreshing, so the configuration of manual refreshing remains unchanged.
-
Config Imports dependencies from the configuration center
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bus-amqp</artifactId> </dependency> Copy the code
-
Config Configure RabbitMQ for the configuration center
spring: application: name: config cloud: # consul configuration consul: . # config configuration config: . # RabbitMQ configuration (new) rabbitmq: The IP address of the server where RabbitMQ resides host: 172.20131.194. Port (TCP) for rabbitMQ port: 5672 Rabbitmq user name and password username: guest password: guest Copy the code
-
Config client imports dependencies
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bus-amqp</artifactId> </dependency> Copy the code
-
Go to the remote repository to find the public configuration file corresponding to the Config client to add
spring: . rabbitmq: host: 172.20131.194. port: 5672 username: guest password: guest Copy the code
-
Config Client bootstrap.yml adds the configuration
spring: cloud: config: . Let the microservice work when there is a problem connecting the message bus to the message server fail-fast: true Copy the code
-
Config Center enables all Web endpoints (including those for remote configuration file refresh)
management: endpoints: web: exposure: include: "*" Copy the code
-
Send a POST request to the configuration server to send a message to RabbitMQ, which tells all servers to refresh the configuration file.
Curl -x POST http://IP address of the S2600: S2600 port/actuator/bus-refreshCopy the code
Note:
- The RabbitMQ Web port is 15672 and the TCP port is 5672.
- You can create your own users on the RabbitMQ Web. This article uses its own guest account.
3. Specify semi-automatic refresh of configurations
It is used by default
Curl -x POST http://IP address of the S2600: S2600 port/actuator/bus-refreshCopy the code
This mode of configuration refresh is broadcast. The configuration center will tell RabbitMQ to broadcast the refresh to all configuration files in the remote repository. However, sometimes we only change the configuration of one service, and the notification of other services is unnecessary, so we need to specify the service for notification.
-
Specify all nodes in a service cluster to automatically refresh configuration files
Curl -x POST http:// service center IP: port service center/physical/bus - refresh/service nameCopy the code
-
Specify a node in a service cluster to refresh the configuration file automatically
Curl -x POST http://IP address of the bSACTUATOR: bSACTUATOR port/ BSACTUATOR /bus-refresh/ BSACTUATOR port: bSACTUATOR port: bSACTUATOR portCopy the code
Configuring Automatic Refresh
In a semi-automatic refresh, we still need to manually send a POST request to the configuration center to notify RabbitMQ of the changes after modifying the configuration file in the remote repository. After the Github Webhock function is used to realize automatic configuration refresh, the configuration file will be automatically refreshed to the corresponding service after modification, without us to manually send a request.
Webhock works like a listener. Github automatically sends a POST request to the configuration center when we modify and submit a configuration file.
1. Configuration webhock
-
Access remote warehouse
-
Add webhock
-
Fill in the Webhock configuration
2. NATAPP penetrates the Intranet
Because a registered user in NATAPP can have two tunnels of different protocols for free, this paper uses NATAPP to achieve Intranet penetration.
-
Log in to NATAPP website, register, log in.
-
Buy free tunnels
-
Get authtoken
-
Downloading a Client
-
Open CMD in the directory of the NATAPP execution file.
-
Start NATAPP, enter natapp-AuthToken = 56f71DB69ea4be2a in CMD
-
Obtain the public IP address after Intranet penetration
-
Fill in the payload URL required in the Webhock configuration with the public IP address
-
Create the Config package in the Config configuration center.
-
Create a Filter to Filter out other unwanted information in the Webhock POST request
import org.springframework.stereotype.Component; import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; import javax.servlet.http.HttpServletResponse; import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.IOException; @Component public class UrlFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException {}@Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest httpServletRequest = (HttpServletRequest)request; HttpServletResponse httpServletResponse = (HttpServletResponse)response; String url = new String(httpServletRequest.getRequestURI()); // Only filters /actuator/bus-refresh requests if(! url.endsWith("/bus-refresh")) { chain.doFilter(request, response); return; } // Get the original body String body = readAsChars(httpServletRequest); System.out.println("original body: "+ body); // Wrap the original request with HttpServletRequest to modify the body content of the POST request CustometRequestWrapper requestWrapper = new CustometRequestWrapper(httpServletRequest); chain.doFilter(requestWrapper, response); } @Override public void destroy(a) {}private class CustometRequestWrapper extends HttpServletRequestWrapper { public CustometRequestWrapper(HttpServletRequest request) { super(request); } @Override public ServletInputStream getInputStream(a) throws IOException { byte[] bytes = new byte[0]; ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes); return new ServletInputStream() { @Override public boolean isFinished(a) { return byteArrayInputStream.read() == -1 ? true:false; } @Override public boolean isReady(a) { return false; } @Override public void setReadListener(ReadListener readListener) {}@Override public int read(a) throws IOException { returnbyteArrayInputStream.read(); }}; }}public static String readAsChars(HttpServletRequest request) { BufferedReader br = null; StringBuilder sb = new StringBuilder(""); try { br = request.getReader(); String str; while((str = br.readLine()) ! =null) { sb.append(str); } br.close(); } catch (IOException e) { e.printStackTrace(); } finally { if (null! = br) {try { br.close(); } catch(IOException e) { e.printStackTrace(); }}}returnsb.toString(); }}Copy the code
Note:
-
Configure the payload URL in the Webhock to be a public IP address. Otherwise, deploy the configuration center to the cloud server, or perform Intranet penetration.
-
If a Filter is not created, Github will report a 400 error when sending a Post request to the configuration center. This is because Spring Boot can’t deserialize properly, so we need to write a filter that returns the Body as empty.