Micro-service Architecture of Android system architecture

Source: Internet
Author: User
<span id="Label3"></p>Directory <ul> <ul> <li>one, Micro-service Architecture Model<br> <ul> <li>1.1 Pattern Description</li> <li>1.2 Mode topology</li> <li>1.3 Avoiding dependencies and scheduling</li> <li>1.4 Precautions</li> <li>1.5 Pattern Analysis</li> </ul></li> <li>second, the Micro-service architecture in Android</li> <li>third, Conclusion</li> </ul> </ul><p><p>In the previous period, we translated the "software architecture model" (the Address of the full book) after the release of Everyone's praise, The book tells the five classic, popular software architecture model, while analyzing the implementation of five models, advantages and disadvantages, for our development work provides valuable guidance. But the problem with the software architecture model is that there are no specific examples to make these theoretical knowledge easier to assimilate, so some students in my development group have feedback: the book looks pretty good, but no specific example feels vaguely. therefore, under the intention to write some combination of Android source code or development of the article to more in-depth talk about these architectural patterns, theory and practice, so that we have a deeper and more specific learning to the charm of these Architectures.</p></p><p><p><b id="arch"></b></p></p>one, Micro-service Architecture Model<p><p>Due to the high flexibility and scalability of the Micro-service architecture model, the industry has developed rapidly in recent Years. But as this architecture pattern is still evolving, there is a lot of confusion among insiders about this model, such as what is the model about? How is it implemented? This article begins with the key concepts, fundamentals, and the pros and cons of this model, because only after a deep understanding of it can you judge whether your application is suitable for this architecture based on the actual Situation.</p></p><p><p><b id="desc"></b></p></p>1.1 Pattern Description<p><p>Regardless of which implementation you choose, there are several common Core concepts that need to be understood. The first concept is a <strong>standalone deployment unit</strong> . 4-1, each component of the MicroServices architecture is deployed as a standalone unit, allowing each unit to communicate through an efficient and streamlined transport pipeline, while still being highly scalable, with a high degree of decoupling between applications and components, making deployment Easier.</p></p><p><p>Perhaps the most important concept to understand this pattern is the service Component. Instead of considering services within the MicroServices architecture, it is best to consider the service components, which can be as small as a single module or as large as an application from a granular level. A service component consists of one or more modules, such as Java classes, that can provide a single function, such as weather conditions for a particular city or town, or as an independent part of a large commercial application, such as a ticket-to-rail query System. In the MicroServices architecture, It is also a great challenge to properly design the granularity of the service Components. This challenge is discussed in detail in the following parts of the service Component.</p></p><p><p><br>Another key concept of the microservices architecture pattern is that it may be a <strong>distributed</strong> architecture, which means that all components within the architecture are fully decoupled and accessed through some kind of remote access Protocol (for example, JMS, AMQP, REST, SOAP, rmi, etc.). The distributed nature of this architecture is key to achieving some of the superior scalability and deployment Features.</p></p><p><p>Another exciting feature of the microservices architecture is that it evolves from the problems of other common architectural patterns, rather than being created as a solution and waiting for problems to Arise. The evolution of the MicroServices architecture has two main sources: monolithic applications using layered architecture patterns and distributed applications using service-oriented Architectures.</p></p> <blockquote> <blockquote> <p>Tip: a single application, that is, an application is a whole.</p> </blockquote> </blockquote><p><p>The process of development from monomer applications to microservices is largely facilitated by continuous delivery of Development. Monomer applications are typically composed of tightly coupled components that are part of another single deployable unit, making it cumbersome and difficult to change, test, and deploy Applications. These factors often cause the application to become brittle, so that every time a new feature is deployed, the entire application will not run if the new functionality throws an Exception. The MicroServices architecture pattern solves this problem by separating the application into multiple deployable units (serviced components) that can be independently developed, tested, and deployed separately from other service Components.</p></p><p><p>Another evolutionary process that leads to the creation of microservices architecture patterns is caused by problems with service-oriented architecture pattern (SOA) Applications. While the SOA model is very powerful, providing unmatched levels of abstraction, heterogeneous connectivity, service scheduling, and ensuring that business objectives are aligned through it capabilities, it is still complex and expensive, it is difficult to understand and implement, and it is too heavyweight for most applications. The MicroServices architecture solves complexity problems by simplifying service concepts, eliminating scheduling requirements, simplifying service component connectivity, and Access.</p></p><p><p><b id="topology"></b></p></p>1.2 Mode topology<p><p>While there are many ways to implement MicroServices architecture patterns, The three main topologies stand out, the most common and popular are: rest api-based topologies, rest-based application topologies, and centralized message Topologies.</p></p> <ul> <ul> <li><strong>rest-based API Topologies</strong><br>Rest-based API topologies are available for Web sites and provide small, self-contained services to external providers through certain Apis. This topology, shown in 4-2, consists of very granular service components (hence the name microservices) that contain one or two modules and perform specific business functions independently of other Services. In this topology topology, these fine-grained service components are typically accessed by the rest-based interface, which is implemented through a single deployed Web API Layer. Examples of this topology include some common, cloud-based, restful Web service that is used by large web sites like yahoo!, Google, and Amazon.</li> </ul> </ul><p><p><br>Figure 4-2</p></p> <ul> <ul> <li><strong>rest-based Application Topologies</strong><br>The rest-based application topology differs from rest-based APIs in that it receives client requests through a traditional web-based application or client application, rather than through a simple API Layer. 4-3, the UI layer of the app is a Web application that provides access to a single deployed service component through a simple rest-based interface. The service components in this topology are different from the rest API topologies, which tend to be larger and more granular, representing a small portion of the entire business application, rather than fine-grained, single-action Services. This topology is common to small and medium-sized enterprises, such as relatively low-complexity applications.</li> </ul> </ul><p><p><br>Figure 4-3</p></p> <ul> <ul> <li><strong>Centralized message topology</strong><br>Another common approach in the MicroServices architecture pattern is the centralized message topology, shown in 4-4. This topology is similar to the rest-based application topology mentioned earlier, and the rest-based application topology uses rest for remote access, while the topology uses a lightweight, centralized messaging middleware (such as ActiveMQ, hornetq, and so on). It is extremely important not to confuse this topology with a service-oriented schema pattern or treat it as an SOA Lite. The lightweight messaging middleware (lightweight message Broker) in this topology does not perform any scheduling, conversion, or complex routing, but instead it is simply a lightweight transport tool that accesses remote service Components.<br>Centralized message topologies are typically applied in larger business applications, or in applications that have more complex control logic to the transport layer to the user interface layer or to the service component Layer. Compared to the simple rest-based topology discussed earlier, the topology benefits from Advanced Queueing mechanisms, asynchronous messaging, monitoring, error handling, and better load balancing and Scalability. The single point of failure and schema bottlenecks associated with centralized proxies have been addressed through proxy clustering and proxy federation, which divides a proxy instance into multiple proxy instances, dividing the throughput load based on the functional area of the System.</li> </ul> </ul><p><p><br>Figure 4-4</p></p><p><p><b id="avoid"></b></p></p>1.3 Avoiding dependencies and scheduling<p><p>One of the main challenges of the MicroServices architecture model is determining the granularity level of the serviced Component. If the service components are coarse-grained, you may not realize the benefits of this architectural pattern (deployment, scalability, testability, and Loose coupling). however, the granularity of the service component will result in additional service scheduling, which could lead to a complex, confusing, costly, and error-prone, heavyweight service-oriented architecture that will transform the microservices architecture Pattern.</p></p><p><p>If you find that you need to dispatch service components from the user interface or API layer within your application, it is likely that the granularity of your serviced component is too fine. similarly, If you find that you need to perform inter-service communication between service components to handle a single request, either the granularity of your serviced component is too fine or the service component is not properly partitioned from a business functional Perspective.</p></p><p><p>Inter-Service communication may result in coupling between components, but can be handled through a shared database. For example, if a service component needs user information to process a network order, it can go to the database to retrieve the necessary data instead of invoking the functionality of the customer service Component.</p></p><p><p>A shared database can handle information needs, but what about shared functionality? If a service component requires functionality that is contained within another service component, or a common function, then sometimes you can copy the shared functionality of the serviced component, thus violating the dry rule. In order to maintain separation of service components and deployment, there is a small subset of redundancy caused by repetitive business logic in the implementation of the MicroServices architecture pattern, which is a fairly common problem in most business applications. The gadget class may fall into this category of duplicated Code.</p></p> <blockquote> <blockquote> <p>Tip: DRY, that is, don ' t repeat yourself.</p> </blockquote> </blockquote><p><p>If you find that even if you do not consider the level of granularity of service components, you still cannot avoid service component scheduling, which is a good sign that this schema pattern may not apply to your app. Because of the distributed nature of this pattern, it is difficult to maintain a single working transaction unit between serviced Components. This approach requires some kind of transaction compensation framework to roll back the transaction, which significantly adds complexity to this relatively simple and elegant architectural pattern.</p></p><p><p><b id="considerations"></b></p></p>1.4 Precautions<p><p>The MicroServices architecture pattern solves many of the problems existing in single-application and service-oriented architecture Applications. Applications built using the MicroServices architecture pattern are typically more robust, provide better scalability, and support continuous delivery, as the main application components are split into smaller, separate deployment Units.</p></p><p><p>Another advantage of this model is that it provides real-time production deployment capabilities, greatly reducing the need for a traditional monthly or weekend "big bang" production Deployment. Because changes are often isolated into a specific service component, only the changing service components need to be deployed. If your service component has only one instance, you can write specialized code in the user interface program to detect an active hot deployment, redirect the user to an error page, or wait for the page as soon as it is Detected. You can also swap multiple instances of a serviced component during real-time deployment, allowing applications to maintain continuous availability during deployment (a Hierarchical schema pattern is difficult to do).</p></p><p><p>The last consideration to consider is that because the microservices architecture pattern may be a distributed architecture, he has some common complex issues with the Event-driven architecture pattern, including contract creation, maintenance, and management, availability of remote systems, remote access authentication and authorization, and so On.</p></p><p><p><b id="analysis"></b></p></p>1.5 Pattern Analysis<p><p>The following table contains feature analysis and ratings for the microservices architecture pattern, with each feature rating based on its own characteristics, capability characteristics based on typical pattern implementations, and what is known about this Pattern.</p></p> <table> <thead> <tr> <th>features</th> <th>rating</th> <th>Analysis</th> </tr> </thead> <tbody> <tr> <td> Overall flexibility </td> <td> high </td> <td> The overall flexibility is the ability to respond quickly to changing environments. Because the service is a standalone deployment unit, changes are often isolated into separate service components, making deployment fast and Easy. At the same time, applications built using this pattern are often loosely coupled and help to promote Change. </td> </tr> <tr> <td> easy to deploy </td> <td> high </td> <td> Each service component is a standalone deployment unit that makes each deployment unit relatively simple and reduces the complexity of deployment. Ease of deployment has become a major advantage of microservices Architectures. </td> </tr> <tr> <td> testability </td> <td> High </td> <td> because the business functions are separated into separate application modules, they can be tested in a local scope, so that the testing work is more targeted. Regression testing of a particular service component is simpler and more feasible than regression testing of the entire monolithic Application. moreover, Since the service components of this model are loosely coupled, from a development perspective, the odds of a change causing the other parts of the application to change are also minimal, and there will be no egg aches that test the entire application for a small change. </td> </tr> <tr> <td> performance </td> <td> low </td> <td> Although you have many advantages in this mode, the communication between the client program and the service is inefficient due to the distributed or cross-process characteristics of the microservices architecture pattern, so it is not suitable for high performance Use the Program. </td> </tr> <tr> <td> Scalability </td> <td> High </td> <td> because the application is divided into separate deployment units, each service component can be scaled independently and allow extended adjustments to the Application. For example, the Administrator function module for stock trading may not need to be extended because users with this feature are more Limited. however, The Transaction Data request service component may need to be extended, because there may be countless people on request every moment of the day, and therefore need to be highly scalable. </td> </tr> <tr> <td> Easy to develop </td> <td> high </td> <td> because the functionality is separated into different service components, development becomes simpler due to the smaller development scope and Isolation. Programmers have a small chance of making a change in one service component that affects other service components, reducing the coordination between the developer or the development Team. </td> </tr> </tbody> </table><p><p><b id="pattern-in-android"></b></p></p>Micro-service Architecture in Android<p><p>In the Android world, the most common thing we see is the 4-5 android Architecture.</p></p><p><p><br>Figure 4-5</p></p><p><p>This is a typical layered architecture, which is divided into application layer, framework layer, native layer and kernel layer. This seems to have nothing to do with the microservices architecture we're talking about today! It is important to note that this is a more macroscopic architecture, and there are other architectural patterns under this layered architecture, and the microservices architecture is one of the most obvious. The Android system is divided into different levels of responsibility, but between the Java Layer (java application and application Framework) and the system service layer (android runtime Environment) the two tiers are communicated through the local c/s mode, which is our microservices Architecture.</p></p><p><p>We know that when the Android system starts, it roughly performs the following four steps:</p></p> <ol> <ol> <li>Init process started;;</li> <li>System Server startup;</li> <li>The Android system service starts and registers the service with the servicemanager;</li> <li>The Android runtime environment is established and the Launcher program is Started.</li> </ol> </ol><p><p>After the init process is started, the Init_parse_config_file method is called to parse the init.rc file and then start up the commands, services, and so on that are specified in the INIT.RC.</p></p><pre class="prettyprint"><code class="language-cpp hljs "><span class="hljs-keyword"><span class="hljs-keyword">int</span></span>Main<span class="hljs-keyword"><span class="hljs-keyword">int</span></span>argc<span class="hljs-keyword"><span class="hljs-keyword">Char</span></span>**argv) {<span class="hljs-comment"><span class="hljs-comment">//code Omission</span></span> <span class="hljs-comment"><span class="hljs-comment">//create a system folder</span></span>mkdir<span class="hljs-string"><span class="hljs-string">"/dev"</span></span>,<span class="hljs-number"><span class="hljs-number">0755</span></span>); mkdir<span class="hljs-string"><span class="hljs-string">"/proc"</span></span>,<span class="hljs-number"><span class="hljs-number">0755</span></span>); mkdir<span class="hljs-string"><span class="hljs-string">"/sys"</span></span>,<span class="hljs-number"><span class="hljs-number">0755</span></span>);<span class="hljs-comment"><span class="hljs-comment">//code Omission</span></span> <span class="hljs-comment"><span class="hljs-comment">//initialize Kernel</span></span>Open_devnull_stdio (); Klog_init (); Property_init (); Process_kernel_cmdline ();<span class="hljs-comment"><span class="hljs-comment">//code Omission</span></span> <span class="hljs-comment"><span class="hljs-comment">//parse init.rc File</span></span>Init_parse_config_file (<span class="hljs-string"><span class="hljs-string">"/init.rc"</span></span>);<span class="hljs-comment"><span class="hljs-comment">//code Omission</span></span> <span class="hljs-keyword"><span class="hljs-keyword">return</span></span> <span class="hljs-number"><span class="hljs-number">0</span></span>;}</code></pre><p><p>Init.rc is a file written by a script known as the Android initialization language. Some of the actions, commands, services, options, and so on are described in this file, and we only care about the Service. A description of the service in Init.rc is roughly the Case.</p></p><pre class="prettyprint"><pre class="prettyprint"><code class="language-xml hljs ">service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server class main socket zygote stream 660 root system onrestart write /sys/android_power/request_state wake onrestart write /sys/power/state on onrestart restart media onrestart restart netd</code></pre></pre><p><p>A zygote service is specified in the Code above, and the service initiates a process called zygote, zygote is the source of everything in the Android world, so the process has it hatched. When you start zygote, the system server process starts, System server is the habitat for all system services, and is the hub for applications to communicate with the zygote process, such as when an app needs to be started, through System server notification zygote Fork a new Process. The Com_ android_ Server_ systemserver is called after system server Starts. The Android_server_systemserver_nativeinit function in the CPP class, in which the ServiceManager instance is obtained and some native services are Started. finally, the Initandloop function that calls the systemserver inner class Serverthread will windowmanagerservice, Activitymanagerservice and other system services registered in servicemanager, These services provide a variety of functions for the system, and finally start the system message loop, the Android operating environment is basically built up.</p></p><pre class="prettyprint"><code class="language-java hljs "><span class="hljs-keyword"><span class="hljs-keyword"></span> public</span> <span class="hljs-class"><span class="hljs-class"> <span class="hljs-keyword">class</span> <span class="hljs-title">systemserver</span> {</span></span><span class="hljs-comment"><span class="hljs-comment">//main Function</span></span><span class="hljs-keyword"><span class="hljs-keyword"></span> public</span> <span class="hljs-keyword"><span class="hljs-keyword">Static</span></span> <span class="hljs-keyword"><span class="hljs-keyword">void</span></span> <span class="hljs-title"><span class="hljs-title">Main</span></span>(string[] Args) {<span class="hljs-comment"><span class="hljs-comment">//code Omission</span></span> <span class="hljs-comment"><span class="hljs-comment">//Initialize native Services.</span></span>Nativeinit ();<span class="hljs-comment"><span class="hljs-comment">//this used-own separate thread, but now it</span> 's</span> <span class="hljs-comment"><span class="hljs-comment">//just The loop we run on the main thread.</span></span>Serverthread thr =<span class="hljs-keyword"><span class="hljs-keyword">New</span></span>Serverthread (); Thr.initandloop (); }}<span class="hljs-comment"><span class="hljs-comment">//inner class</span></span>Class Serverthread {<span class="hljs-keyword"><span class="hljs-keyword"></span> public</span> <span class="hljs-keyword"><span class="hljs-keyword">void</span></span> <span class="hljs-title"><span class="hljs-title">Initandloop</span></span>() {<span class="hljs-comment"><span class="hljs-comment">///1, start the main thread message loop</span></span>Looper.preparemainlooper ();<span class="hljs-comment"><span class="hljs-comment">//code Omission</span></span> <span class="hljs-keyword"><span class="hljs-keyword">Try</span></span>{<span class="hljs-comment"><span class="hljs-comment">///2, registering each system service in ServiceManager</span></span> <span class="hljs-comment"><span class="hljs-comment">//add Packagemanagerservice</span></span>PM = Packagemanagerservice.main (context, installer, wm = Windowmanagerservice.main (context, power, display, INP utmanager, wmhandler, factorytest! = systemserver.factory_test_low_level,!firstboot , onlycore);<span class="hljs-comment"><span class="hljs-comment">//add Windowmanagerservice</span></span>Servicemanager.addservice (context.window_service, wm);<span class="hljs-comment"><span class="hljs-comment">//dozens of registration of services, code omission</span></span>}<span class="hljs-keyword"><span class="hljs-keyword">Catch</span></span>(runtimeexception E) { }<span class="hljs-comment"><span class="hljs-comment">///3, Start message loop</span></span>Looper.loop (); }}<span class="hljs-comment"><span class="hljs-comment">//end of Servicethread</span></span>}<span class="hljs-comment"><span class="hljs-comment">//end of Systemserver</span></span></code></pre><p><p>The framework layer (client) and the native system service (server Side) are not directly called, but through the binder mechanism, the client code through the Java side of the service proxy and bidner mechanism to the native service to initiate the request, The specific work is given to native system services to Achieve. So the framework and the architecture of the native layer are shown in 4-6.</p></p><p><p></p></p><p><p>This architecture is similar to the above mentioned in the api-based microservices architecture, native layer system services to complete the specific functions, the Java layer provides access to the native system services interface, between them through the binder mechanism for communication, Java layer and native layer is a local c/ S Architecture. If you use a web-requested app as a metaphor, the app client plays the Java layer, and the native Layer system service corresponds to the service side, and the communication mechanism is changed from HTTP to Binder. Native layer system service up to dozens of kinds, each system service responsibility is clear, single, has the good Cohesion. For example, Windowmanagerservice is only responsible for managing screen window related Operations. Through this micro-service architecture, the Java layer and native layer coupling is very low, scalability is very high, but also the Java layer hidden a complex implementation, making the whole system more clear and Flexible.</p></p><p><p><b id="the-end"></b></p></p>Summarize<p><p>The microservices architecture stands out in each architectural pattern for its excellent flexibility and scalability, but one weakness is its relatively low performance. Because both the client and the service provider require IPC or even network requests, This is a high-cost communication. Both the client and server are on-premises in android, so the IPC mechanism is Required. Instead of choosing traditional IPC mechanisms like sockets and pipelines, Android chose more flexible, concise, and fast, low memory-consuming binders, which also greatly improved the performance and overhead of the microservices architecture in Android Systems. therefore, If you use this architecture in ordinary applications, the first thing to consider is the cost of performance, flexibility, the benefits of memory is greater than the drawbacks of performance degradation, which need to be determined by their own circumstances.</p></p> <p><p>Micro-service Architecture of Android system architecture</p></p></span>

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.