Best Development Practices for SpringCloud Microservices

  • 2021-10-24 23:02:29
  • OfStack

Nowadays, micro-service development based on SpringCloud is becoming more and more popular, and various open source projects on the Internet emerge one after another. In practical work, we can refer to open source projects to achieve many out-of-the-box functions, but we must abide by the 1 fixed conventions and specifications.

In this paper, combined with some problems encountered in our actual development, we have sorted out a practical specification for micro-service development. Welcome all the big brothers to give advice.

Maven specification

1. All projects must have a unified parent module

All micro-service projects rely on this parent, parent for management of dependent versions, maven repositories, jar version upgrades and maintenance

There are custom modules such as core, starter, rate-limit in the lower layer of parent

2. The role of the core core package:

Agreement on various development specifications in the form of POJO; For example, BaseEntity, system 1 is included and returned All kinds of 2-square and 3-square components can be used out of the box AutoConfig;; Various help classes to improve development efficiency, etc. XXXUtil

Note: All scope dependencies of the core package must be provided to avoid passing dependencies and load Bean conditionally with Condition annotations such as @ ConditionalOnClass (Ribbon. class), @ ConditionalOnBean (StringRedisTemplete. class)

3. starter module

If you need to rely on more than 10 starter per service, you can build a unified starter module to help them integrate 1 dependencies, manage dependency sets and simplify dependencies

4. rate-limit module

Used to place non-general self-developed components

5. Distinguish Release version from Snapshot version correctly

Note: If Snapshot version, then mvn deploy will be automatically released to the snapshot version library, and the use of snapshot version of the module, in the case of not changing the version number, directly compile packaging, Maven will automatically download the latest snapshot version from the mirror server.

If it is Release version, it will be automatically released to the official version library when mvn deploy, while using the official version module, if the module already exists locally during compilation and packaging, it will not take the initiative to download it on the mirror server without changing the version number.

In short:

Release: Official version. You can't continue to use this version number with bug

Snapshot: Snapshot version. If you have bug, you can continue to use the same version number. It can be upgraded automatically. Recommended

Service invocation

By introducing sdk call between standard services, service consumers need to rely on api provided by producers, which is convenient to upgrade with snapshot


account
	account-api
	account-service

account-api module to put consumer needs to use things, api interface, vo, into the parameters, etc...


public interface AccountApi {
    ...
}

account-service implements the interface provided by account-api


@RestController
@Log4j2
@Api(tags = " User interface ")
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class AccountController implements AccountApi {
    ...
}

Consumers call the producer through feign, directly integrate the interface provided by the producer and handle the fuse


@Component
@FeignClient(name = "account-service",fallbackFactory = AccountClientFallbackFactory.class)
public interface AccountClient extends AccountApi {
    ...
}

@Component
public class AccountClientFallbackFactory implements FallbackFactory<AccountClient> {

    @Override
    public AccountClient create(Throwable throwable) {
        AccountClientFallback accountClientFallback = new AccountClientFallback();
        accountClientFallback.setCause(throwable);
        return accountClientFallback;
    }

}

@Slf4j
public class AccountClientFallback implements AccountClient {
    @Setter
    private Throwable cause;

    @Override
    public ResultData<AccountDTO> getByCode(String accountCode) {
        log.error(" Query failed , Interface exception " ,cause);
        AccountDTO account = new AccountDTO();
        account.setAccountCode("000");
        account.setAccountName(" Test Feign");
        return ResultData.success(account);
    }

}

Restful Design Specification

An API is a developer's UI-just like any other UI 1, it is important to ensure that the user experience is seriously considered!

You can use the following two formats:

/Version/Access Control/Domain Object /Version/Access Control/Domain Object/Action

Domain objects need to follow the following constraints:

Domain objects use nouns instead of verbs Directly use domain object names using/ticket instead of plural/tickets Domain object relational expression should not exceed 2 layers at most, such as/ticket/12/message Need to correctly distinguish GET PUT POST DELETE request methods What cannot be expressed by the noun + request method can be extended to/domain objects/verbs such as POST/user/login

Access control is carried out on the interface at the gateway layer, and the rules of access control are as follows:

pb-public All requests are accessible

pt-protected requires token authentication before it can be accessed

pv-private cannot be accessed through the gateway and can only be called internally by the microservice

df-default gateway requests token authentication, and requests parameters and returned results for encryption and decryption

Version:

With micro-service as the strength, the whole service is upgraded

For example, a microservice has the following API

GET /v1/pb/user

POST /v1/pb/user

PUT /v1/pb/user

If POST /v1/pb/user If you need to upgrade, you need to upgrade the whole microservice/v1 to/v2, and ensure that the old version of api which is compatible with the version can continue to be accessed

GET/v2/pb/user is equivalent to GET/v1/pb/user

POST/v1/pb/user marked obsolete

POST /v2/pb/user

PUT/v2/pb/user is equivalent to PUT/v1/pb/user

Code implementation:

1. The GET mode {version} can be any value, v1, v2, for example: @ GetMapping ("/{version}/pb/user")

2. The POST method enforces V1 and is marked obsolete, but can still be used


@Deprecated
@PostMapping("/v1/pb/user")

3. POST {version} should be the current version, only v2


@PostMapping("/{version}/pb/user")

Gateway

It can be realized by its own service without undertaking the micro-service authentication function (simple services can be authenticated directly at the gateway layer) The differences between gateway authentication and micro-service authentication are explained in detail in my other articles. Please refer to this article: http://t.hk.uy/2c3 Need to implement access control permissions, combined with the Restful specification above, mask /pv/** Such as special requests Need to implement gray publishing function

When developing joint debugging, it is necessary to import server traffic locally, and filter service instances by combining metadata and request header of nacos. Refer to this article for implementation: http://t.hk.uy/2c6


Related articles: