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 serviceshttp://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 itnginx -s reloadYou must restart nginx to reload the configuration. This is when we visitlocalhost:9200/zxhtom/startIt’s essentially being representedhttp://192.168.44.131:9200/zxhtom/startOn 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 localD: \ study \ PageOffice_4 6.0.3 _JavaThis folder acts as an entry point to the local port 90. We’re throughlocalhost:90/index.htmlI can access the localD: \ study \ PageOffice_4 6.0.3 _Java \ index HTMLThe 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 throughupstreamTo define the service and define the policy for the service. Finally we use it directly in serverupstreamThe 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 aboveRibbon.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 aboveAbstractServerPredicatePredicateImplementation 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 upBaseLoadBalancerFor load balancing. Its internal rule defaults tonew RoundRobinRule()Because we introducedio-jmnarloch. First look at the inner class structure

  • io-jmnarlochIt’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 packageRibbonDiscoveryRuleAutoConfigurationRule is the load balancing class in the Ribbon defined by the Rule package.

  • Power toBaseLoadBalancerWe can see that rule is usrule.MetadataAwareRuleThis 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 configuringDiscoveryEnabledRuleThere are at the time of registration@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)Represents scope

How does MetadataAwareRule filter services

  • throughMetadataAwareRuleFinally, 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.MetadataAwarePredicateEventually inheritAbstractServerPredicate. whileAbstractServerPredicate # chooseRoundRobinAfterFilteringDepends on getEligibleServers’ to get the appropriate list of services.
  • inAbstractServerPredicateImplemented 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
  • EligibleTranslate 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 aboveAbstractServerPredicateWe can see in the structure diagram that exceptDiscoveryEnabledPredicateIn 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