Huawei architects talk about how to understand the use of modules and microservices, and officially join ByteDance

1.3, explicit dependencies

Having a modular system means that different components have to work together. You better have a good way of expressing (and validating) their relationship.

The above principles can be implemented through microservices. Whereas a microservice can be implemented in any way as long as it exposes a well-defined interface (usually a REST API) to other services. Its implementation details are internal to the service and can be changed without system-wide impact or coordination. However, the dependencies between microservices are usually not very clear during development, resulting in possible service orchestration failures during runtime.

As a result, microservices implement important principles of modularity, leading to tangible benefits:

  • Teams can work and scale independently.
  • Microservices are small and focused, reducing complexity.
  • Services can be changed or replaced internally without global impact.

This actually introduces a lot of operational complexity as we move from a (albeit somewhat bloated) application to a distributed microservice system. Suddenly, you need to constantly deploy many different (possibly containerized) services. New problems arise: service discovery, distributed logging, tracing, etc. Errors under distributed computing are now more prone to occur. Versioning of interfaces and configuration management can also become a major concern. And the list of questions just keeps growing.

It turns out that the connections between microservices are as complex as the combined business logic of all individual microservices. While there are problems with "spaghetti code" in the monolithic code base, having network boundaries between the two can escalate these tangled issues into downright painful.

ps: spaghetti code is a pejorative term for unstructured and difficult to maintain source code. Can be caused by a variety of factors, such as volatile project requirements, lack of programming style rules, and lack of ability or experience.

2. Modular alternatives

**Does this mean we're either relegated to big messy apps, or have to drown in the insane complexity of microservices? **Modularity can also be achieved in other ways. What matters is that we can effectively draw and enforce boundaries during development. But we can also achieve this by creating a large, well-structured application. Of course, this means that we tend to take help from programming languages ​​and development tools to enforce the principles of modularity.

For example, in Java, there are several module systems that help in building applications. OSGi is the most famous one, but with the release of Java 9, a native module system was added to the Java platform itself. This feature of modules as a first-class construct is now part of the language and platform. Java modules can express dependencies on other modules and expose and export interfaces while strongly encapsulating implementing classes. Even the Java platform itself (a huge code base) is modularized using the new Java module system.

Other languages ​​provide similar mechanisms. For example, JavaScript gained a module starting with ES2015

"Analysis of Java interview questions in first-line manufacturers + back-end development study notes + latest architecture explanation video + actual project source code handouts"

[docs.qq.com/doc/DSmxTbFJ1cmN1R2dB] Full content open source sharing

block system. Prior to this, Node.js already provided a non-standard module system for JavaScript backends. However, as a dynamic language, JavaScript has weak support for enforcing interfaces (types) and encapsulation between modules. Consider using TypeScript on top of JavaScript to gain this advantage again. Microsoft's .Net Framework does have Java-like strong typing, but it doesn't have a direct equivalent to Java's upcoming module system in terms of strong encapsulation and explicit dependencies between assemblies. Nonetheless, a good modular architecture can be achieved by using the Inversion-of-Control pattern standardized in .Net Core and by creating logically related assemblies. Even C++ is considering adding a module system in a future version. Many languages ​​are increasingly interested in modularity, and modularity itself is a compelling development.

When we consciously use the modularity capabilities of our development platform, you can achieve the same modularity benefits we previously attributed to microservices. Essentially, the better the module system, the more help you can get during development. Different teams can work on different parts, where only well-defined interfaces are touchpoints between teams. However, at deployment time, modules are grouped together in a deployment unit. This way, you can prevent the substantial complexity and costs associated with migrating to microservices development and management. Of course, this means that every module cannot be built on different technology stacks, but for most companies and development teams, can they really master multiple technology stacks?

3. Design module

Creating good modules requires the same design requirements as creating good microservices. A module should model a single bounded context of a business domain. Choosing a microservice boundary is an architecturally important decision that can have costly consequences if done wrong. Whereas module boundaries in a modular application are easier to change. Type systems and compilers often support refactoring across modules. Redrawing microservice boundaries requires a lot of human interaction to keep from blowing up at runtime.

In many ways, modules in statically typed languages ​​provide a better structure for well-defined interfaces. Calling a method through a typed interface exposed by another module is much more robust to changes than calling a REST endpoint on another microservice. REST+JSON is everywhere, but without a (compiler-checked) schema, it's not a sign of well-typed interoperability. What's more, many module systems allow expressing dependencies on other modules, and when those dependencies are violated, the module system forbids doing so, at least with a clear hint, but the dependencies between microservices are only at runtime implemented at times, resulting in a system that is difficult to debug.

Modules are also the natural unit of code ownership. Teams can be responsible for one or more modules in the system. The only thing shared with other teams is the public API of their modules. At runtime, there is less isolation between modules than with microservices. After all, everything is still running in the same process.

There's no reason why a module in a monolith can't own its data like a good microservice does. Sharing within a modular application can then take place through well-defined interfaces or messages between modules, rather than through a shared data store. The big difference with microservices is that everything is ongoing. Eventual consistency issues should not be underestimated. With modules, eventual consistency can be a deliberate strategic choice rather than an inevitable one. With microservices, there is no choice: only eventual consistency.

4. When is microservices right for your organization?

**So when should you move to microservices? **So far, we have mainly focused on solving complexity problems through modularization. For this, both microservices and modular applications are fine. But there are different challenges beyond those presented so far.

  • **When a company has the scale of Google or Netflix, there is every reason to embrace microservices. **This means, the ability to build your own platform and toolkit, and the number of engineers is sufficient. But most organizations don't operate at this scale. Even if the company one day becomes a billion-dollar unicorn, starting with a large, modular application won't pose a problem.

  • **Another good reason to start separate microservices is that different services are inherently better suited for different technology stacks. **That is, the lock must have sufficient scale to attract talents in these different technology stacks and keep these platforms running normally.

  • **Microservices can also deploy different parts of the system independently, which is difficult (or even impossible) in most modular platforms. **Isolated deployment increases the resilience and fault tolerance of the system. Also, scaling characteristics can be different for each microservice. Different microservices can be deployed to matching hardware. Modular monoliths can also be scaled horizontally, but more subtle ones are difficult. But in general practice, modularization can support long-term business development.

V. Conclusion

**how to choose? It really depends on the environment, the organization and the application itself. **We can start with a modular application and move to microservices whenever we choose, and we can also use modules to build microservices internally.

If we're after the benefits of modularity, make sure we don't fall into the mindset that we can only use microservices. Use built-in modular functions or frameworks in your favorite or best technology stack as much as possible.

Author: Reprinted by Mark,
please indicate the source

Continue to follow me and share more dry goods.

おすすめ

転載: blog.csdn.net/m0_65484000/article/details/122196513