当前位置:网站首页>Microservice system design -- microservice invocation design

Microservice system design -- microservice invocation design

2022-06-27 04:21:00 Zhuangxiaoyan

Abstract

Has introduced Nacos Basic components , Completed the service registration and discovery mechanism , All services can be managed and configured uniformly , Facilitate inter service calls . This chapter will combine the requirements , Make calls between services , Complete function development .

One 、 Common service invocation methods

There are two common methods of calling between services :RPC And HTTP,RPC Full name Remote Produce Call Remote procedure call , Fast , Efficient , In the early WebService Interface , Now the hot Dubbo、gRPC 、Thrift、Motan etc. , All are RPC Typical representative of , Interested friends can find relevant information , Get to know more about .

HTTP agreement (HyperText Transfer Protocol, Hypertext transfer protocol ) It is the most widely used network transmission protocol on the Internet , be-all WWW Documents must comply with this standard . There are no language restrictions on service providers and callers , It is more in line with the idea that microservice language is irrelevant . Hot nowadays RESTful Form of development , through HTTP Agreement to achieve . In this case, simplicity and Spring Cloud Basic characteristics of , Decided to adopt HTTP In the form of , Interface interaction , Complete the call between services .Spring Cloud The common calling methods under the system are :RestTemplate 、 Ribbon and Feign These three .

  1. RestTemplate, yes Spring Provided for access Rest Client of service ,RestTemplate Provides a variety of convenient remote access Http Method of service , Can greatly improve the writing efficiency of the client .
  2. Ribbon, from Netflix Produce , The more well-known role is that of the client Load Balance( Load balancing ).
  3. Feign, By the same Netflix Produce , Is a more convenient HTTP client , It's like calling a local method , There's no sense of a remote method being called . Inside, too Ribbon To do the load balancing function .

because Ribbon Already integrated in Feign in , Let's just introduce RestTemplate and Feign How to use .

Two 、RestTemplate Application

functional requirement : When a member binds a mobile number , At the same time, the corresponding integral is added . The member binding mobile number is completed in the member service , Increase member points and complete in the points service . The request path is the client -> Member services -> Points service .

Methods of responding to client requests

 @RequestMapping(value = "/bindMobileUseRestTemplate", method = RequestMethod.POST)
    public CommonResult<Integer> bindMobileUseRestTemplate(String json) throws BusinessException{
        CommonResult<Integer> result = new CommonResult<>();
        log.info("bind mobile param = " + json);
        int rtn = memberService.bindMobileUseRestTemplate(json);
        result.setRespData(rtn);
        return result;
    }

do RestTemplate Configuration work , Otherwise, it cannot be used normally .

@Configuration
public class RestTemplateConfig {

    @Bean
    public RestTemplate restTemplate(ClientHttpRequestFactory simpleClientHttpRequestFactory){
        return new RestTemplate(simpleClientHttpRequestFactory);
    }

    @Bean
    public ClientHttpRequestFactory simpleClientHttpRequestFactory(){
        SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
        return factory;
    }
}

stay MemberService Processing requests in , The logic is as follows :

@Autowired
RestTemplate restTemplate;

@Override
    public int bindMobileUseRestTemplate(String json) throws BusinessException {
        Member member = JSONObject.parseObject(json, Member.class);
        int rtn = memberMapper.insertSelective(member);
        // invoke another service
        if (rtn > 0) {
            MemberCard card = new MemberCard();
            card.setMemberId(member.getId());
            card.setCurQty("50");

            MultiValueMap<String, String> requestMap = new LinkedMultiValueMap<String, String>();
            requestMap.add("json", JSONObject.toJSONString(card).toString());
            HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<MultiValueMap<String, String>>(
                    requestMap, null);

            String jsonResult = restTemplate.postForObject("http://localhost:10461/card/addCard", requestEntity,
                    String.class);

            log.info("creata member card suc!" + jsonResult);
        }

        return rtn;
    }

use postForObject Method for generating integral record in formal request integral service , And pass the corresponding parameters . The method in the integral sub service is relatively simple , The method that accepts the call request :

@RequestMapping("card")
@RestController
@Slf4j
public class MemberCardController {

    @Autowired
    MemberCardService cardService;

    @RequestMapping(value = "/addCard", method = RequestMethod.POST)
    public CommonResult<Integer> addCard(String json) throws BusinessException {
        log.info("eclise service example: begin add member card = " + json);
        //log.info("jar service example: begin add member card = " + json);
        CommonResult<Integer> result = new CommonResult<>();
        int rtn = cardService.addMemberCard(json);
        result.setRespData(rtn);
        return result;
    }
}

  The actual business logic processing part consists of MemberCardService Done in interface .

@Service
@Slf4j
public class MemberCardServiceImpl implements MemberCardService {

    @Autowired
    MemberCardMapper cardMapper;

    @Override
    public int addMemberCard(String json) throws BusinessException {
        MemberCard card = JSONObject.parseObject(json,MemberCard.class);
        log.info("add member card " +json);
        return cardMapper.insertSelective(card);
    }
}

Start member services separately 、 Points service has two items , adopt Swagger Interface UI Make a simple test .

RestTemplate Default dependency JDK Provide HTTP The ability to connect , in the light of HTTP request , Different methods are available for use , As opposed to the original HTTP Asking is a step forward , But after using the above code , I found it was not elegant enough . Can you call the local interface , Call a third-party service ? Let's introduce Feign Application , Absolutely make you like Feign How to invoke .

3、 ... and 、Feign Application

Fegin The greatest convenience of the call to is , Mask the underlying connection logic , It allows you to call third-party services as if you were calling a local interface , Less code, more elegant . Of course , The service invocation can only be completed normally under the coordination of the service registry , and RestTemplate I don't care if the service registry is working properly .

3.1 introduce Feign

Feign By Netflix Another open source framework developed to realize load balancing , It encapsulates the Ribbon and RestTemplate, Realized WebService Interface oriented programming , Further reduce the coupling degree of the project , Because it encapsulates Riboon and RestTemplate , So it has the functions of these two frameworks . In the member module pom.xml Add jar quote

<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

Add... In the module startup class @EnableFeignClients annotation , For normal use Feign Related functions , When starting, start to @FeignClient Annotated package scan , And scan to the relevant interface client .

//#client  The catalogue is  feign  Directory of the interface 
@EnableFeignClients(basePackages = "com.mall.parking.member.client")
 Front end request response method 

    @RequestMapping(value = "/bindMobile", method = RequestMethod.POST)
    public CommonResult<Integer> bindMobile(String json) throws BusinessException{
        CommonResult<Integer> result = new CommonResult<>();
        log.info("bind mobile param = " + json);
        int rtn = memberService.bindMobile(json);
        result.setRespData(rtn);
        return result;
    }

Interface writing

To write MemberCardClient, And the integral service call , The interface and the related methods in the integral service implement one-to-one binding .

@FeignClient(value = "card-service")
public interface MemberCardClient {

    @RequestMapping(value = "/card/addCard", method = RequestMethod.POST)
    public CommonResult<Integer> addCard(@RequestParam(value = "json") String json) throws BusinessException;

    @RequestMapping(value = "/card/updateCard", method = RequestMethod.POST)
    public CommonResult<Integer> updateCard(@RequestParam(value = "json") String json) throws BusinessException;
}

Note that RequestParam No PathVariable , PathVariable Is to take values from the path ,RequestParam Is to take values from parameters , Different usage .

When using , direct @Autowried It can be used like a local interface , This completes the code writing , Let's verify the accuracy of the logic .

  1. Guarantee nacos-server Starting
  2. To start, respectively, parking-member,parking-card Sub service
  3. adopt parking-member Of swagger-ui Interface , Call the member binding mobile number interface ( Or adopt PostMan Tools )

Under normal circumstances ,park-member,park-card Both data tables in the two libraries have data generation .

that ,fallback When does it work ? Good verification , When the points service is closed , And then call the integral generation method in the integral service again , You will find that the direct call is MemberCardServiceFallback The method in , Respond directly to the caller , Avoid calling timeouts , A long wait .

3.2 Load balancing

As mentioned earlier Feign Has been integrated by default Ribbon function , So you can go through Feign Load balancing directly . Start two card-service example , open Nacos Console , The instance has been successfully registered . Re pass swagger-ui or PostMan Tool access several times bindMobile Method , Log output through console , You can find the request in two card-service Execute in turn in the instance .

How to change the default load balancing policy ? Find out first Ribbon Several load policies are provided : Random 、 polling 、 retry 、 Response time weight and the most idle connection , They correspond as follows :

  • com.netflix.loadbalancer.RandomRule
  • com.netflix.loadbalancer.RoundRobinRule
  • com.netflix.loadbalancer.RetryRule
  • com.netflix.loadbalancer.WeightedResponseTimeRule
  • com.netflix.loadbalancer.BestAvailableRule

Because it is client load balancing , The following configuration must be added to the service caller item to achieve the purpose of adjustment .

card-service: ribbon: NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule

It can also be done through Java Form adjustment of code , Placed under the project startup class

      @Bean
    public IRule ribbonRule() {
        //  Load balancing rules , Change to random 
        return new RandomRule();
//        return new BestAvailableRule();
//        return new WeightedResponseTimeRule();
//        return new RoundRobinRule();
//        return new RetryRule();
    }

thus , We passed a " Member binding mobile number , And increase the corresponding points of members " The function of , Complete a normal service call in two ways , And tested the configuration and use of client load balancing .

After mastering the call between services , Without considering non business functions , You can basically write most of the business logic code in this case , You can refer to the user stories you disassembled , Or the main business process diagram , Do it now , Perfect the code . Service invocation is a frequently used function among microservices , It is especially important to choose a simple way to invoke . Leave a thought question as usual : This paper uses the client load balancing technology , Is it any different from the load balancing technology we often mention ?

The difference between client-side balance and server-side balance ?

Server side load balancing : for example Nginx, adopt Nginx Load balancing , Send the request first , Then through the load balancing algorithm , Choose one of the servers to access ; That is, load balancing algorithm is allocated on the server side .

Client load balancing : for example spring cloud Medium ribbon, The client will have a list of server addresses , Select a server by load balancing algorithm before sending the request , Then visit , This is client load balancing ; That is, load balancing algorithm is allocated on the client side .Ribbo It's based on HTTP and TCP Client load balancer , When we will Ribbon and Eureka When used together ,Ribbon From Eureka Go to the registry to get the server list , Then conduct polling access to achieve the role of load balancing , The client load balancing also needs a heartbeat mechanism to maintain the validity of the server list , Of course, this process needs to be completed together with the service registry .

Blog reference

原网站

版权声明
本文为[Zhuangxiaoyan]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/178/202206270411018091.html