This article has participated in the weekend study plan, click the link to view the details
From the perspective of routing proxy, common routing proxy methods in reading sets are used
Common way
nginx+lua
-
Nginx is a high-performance HTTP reverse proxy server. In our previous projects we used Nginx for two main purposes: direction proxy + static resource server management
-
Click me to download it
-
Nginx is also very convenient to start after downloading, the author here is a Demonstration of the Windows version. You can either click on the app or launch it directly from the command line./nginx or nginx. Depending on the system
The service broker
- Under normal circumstances, the proxy is configured using a Server under HTTP. For example, we need a simple proxy for one of our services
http://192.168.44.131:9200
. The desired effect is that the interface provided by the service can be accessed through the local localhost.
server { listen 9200; server_name localhost; The location / {proxy_pass http://192.168.44.131:9200; #root html; #index index.html index.htm; }}Copy the code
- Of course, after the configuration, we need to do it
nginx -s reload
You must restart nginx to reload the configuration. This is when we visitlocalhost:9200/zxhtom/start
It’s essentially being representedhttp://192.168.44.131:9200/zxhtom/start
On this interface.
Static resource agent
- Above we said in addition to the service proxy. Nginx can also be used as a static resource server.
server{ listen 90; server_name localhost; Location / {root D:\study\ pageoffice_4.6.0.3_java; index index.html; }}Copy the code
- It also uses the SERVER under HTTP. This code represents the local
D: \ study \ PageOffice_4 6.0.3 _Java
This folder acts as an entry point to the local port 90. We’re throughlocalhost:90/index.html
I can access the localD: \ study \ PageOffice_4 6.0.3 _Java \ index HTML
The file.
Load balancing
upstream redis { hash $remote_addr consistent; # $binary_remote_addr; Server 192.168.44.131:6379 weight=5 max_fails=3 fail_timeout=30s; Server 192.168.44.132:6379 weight=1 max_fails=3 fail_timeout=30s; } server { listen 6379; #redis server listening port proxy_connect_timeout 10s; proxy_timeout 300s; # set the timeout period between the client and proxy service. If no operation is performed within 5 minutes, the service will be automatically disconnected. proxy_pass redis; }Copy the code
- Sometimes our services are not just single-node services. If it is distributed, we need to implement a load balancing strategy for the service. At this point, we can’t just agent services. We need to add a load policy. We’re through
upstream
To define the service and define the policy for the service. Finally we use it directly in serverupstream
The service name of the The weight is the weight setting for polling services in the cluster.
Common commands
Exe -s reload Close: nginx.exe -s stop Check configuration validity: nginx.exe -t
zuul
- Zuul is Netflix’s open source project, and I’ve covered zuul pretty well in previous articles. Click on the zuul chapter
- With Zuul we can implement dynamic routing, authentication and authorization, dynamic filters, and ultimately customizable service fuses in conjunction with Hystix
- Zuul can also implement grayscale publishing which can solve our downtime publishing problem. Think of zuul for grayscale publishing if your system is up for 24 hours
Gray scale extension
- Above, we realized the route forwarding by the parameters specified in the request. The realization principle is based on the parameter attribute of Eureka’s metadata.
- But we’ve probably come across software that treats different regions differently in everyday life.
- For example, Alipay Ant Forest has different strategies in different cities
- Let’s say you’re invited to participate in the inside version of an application
- All of these are called grayscale publishing, and the principle is very simple: there are actually multiple instances, and Zuul forwards them to different instances based on the characteristics of the request. Different cities are routed by region, and the inside of the invitation is routed by personal user information. None of them can be implemented without what we have described above
Ribbon.Predicate
. Scaling grayscale publishing is a mustPredicate
Predicate
- The purpose of this class is to make assertions, which is an idea that Google came up with. Click on me specifically about Google
- In the Ribbon section, we learned how the Ribbon performs load balancing and its internal load balancing strategies by reading source code. Those interested can click on the home page.
- Today we’ll take a look at how the ribbon filters after fetching a list of services before load balancing.
// Return an assertion true or false based on input
@GwtCompatible
public interface Predicate<T> {
This method has the following requirements: (1) it does not pollute any data; (2) equality in T's equals is the same effect in apply
boolean apply(@Nullable T input);
// Returns whether the two predicates are the same. Generally, Predicate implementations don't need to override equals. If the implementation can indicate whether the predicate is the same or not based on its own needs. What does it mean to be the same when two predicate objects are the same when they apply
@Override
boolean equals(@Nullable Object object);
}
Copy the code
- Now let’s use Predicate to implement simple data filtering. Of course some people will say why not use Java8 Stream filtering. This is just to pave the way for service filtering in the Ribbon. Why doesn’t the ribbon use streams? The individual characters, Google Predicate, are a lot easier to decouple.
@Test
public void pt(a) {
List<User> userList = new ArrayList<>();
for (int i = 0; i < 100; i++) {
userList.add(new User(Long.valueOf(i+1), "Zhang"+(i+1)));
}
Predicate<User> predicate = new Predicate<User>() {
@Override
public boolean apply(User user) {
return user.getId() % 2= =0; }}; ArrayList<User> users = Lists.newArrayList(Iterables.filter(userList, predicate)); System.out.println(users); }Copy the code
AbstractServerPredicate
The premise to back
- You can see this in our class structure diagram above
AbstractServerPredicate
是Predicate
Implementation class of. This class is also the key role the Ribbon plays in retrieving the list of services. Because the following are based on this class function extension.
Jmnarloch met
- This is what I do in the RIbbon. We can see where Ribbon ends up
BaseLoadBalancer
For load balancing. Its internal rule defaults tonew RoundRobinRule()
Because we introducedio-jmnarloch
. First look at the inner class structure
io-jmnarloch
It’s not very complicated inside, at least compared to Ribbon and Feign, it’s really simple. An internal package of four
package | role |
---|---|
api | Provide context for external use |
predicate | Provides a filter to get a list of services |
rule | Implementation of load balancing policies in the Ribbon |
support | Auxiliary package for the above |
Register load Rule
- We can see it in the support package
RibbonDiscoveryRuleAutoConfiguration
Rule is the load balancing class in the Ribbon defined by the Rule package.
- Power to
BaseLoadBalancer
We can see that rule is usrule.MetadataAwareRule
This class. This is different from what we said in the ribbon section. In the ribbon section, we said that we need to customize rules in@RibbonClient(name = "CLOUD-PAYMENT-SERVICE",configuration = MySelfRule.class)
This way. - It’s actually configuring
DiscoveryEnabledRule
There are at the time of registration@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
Represents scope
How does MetadataAwareRule filter services
- through
MetadataAwareRule
Finally, PredicateBaseRule#choose selects the list of services
-
The predicate is what we get from the getPredicate() method in our choose. So the Ribbon filters the service through MetadataAwarePredicate before it selects the service.
-
After the access to the filter object, we will carry out chooseRoundRibbinAfterFiltering.
Back to AbstractServerPredicate
- Said on May end to perform chooseRoundRobinAfterFiltering Predicate. Remember the schematic of Predicate from the beginning.
MetadataAwarePredicate
Eventually inheritAbstractServerPredicate
. whileAbstractServerPredicate
#chooseRoundRobinAfterFiltering
Depends on getEligibleServers’ to get the appropriate list of services. - in
AbstractServerPredicate
Implemented a lot of chooseXXX methods. Because the ribbon defaults to polling, the BaseLoadBalance method is Round. These we can modify the way. I won’t repeat it here Eligible
Translate as appropriate. GetEligibleServers translates to get a list of suitable services.
- We can clearly see that the final filtering logic falls on the Apply method.
-
This is where we configured our service information through metadata-map:lancher above.
-
Here’s AbstractServerPredicate simplified. The main method is getEligibleServers.
A subclass
- In the above
AbstractServerPredicate
We can see in the structure diagram that exceptDiscoveryEnabledPredicate
In addition to this subclass, there are four other subclasses.
A subclass | role |
---|---|
AvailabilityPredicate | Filter unavailable servers |
CompositePredicate | The combined mode ensures a certain number of services. In other words, if there are too few services, fallbacks will know that the number of services meets the requirements one by one |
ZoneAffinityPredicate | Select a Server in the specified zone |
ZoneAvoidancePredicate | Avoid using a qualified server. Predicate works opposite to ZoneAffinityPredicate |