Overview of microservices
1 what is micro service?
Microservice architecture is an architecture mode, or architecture style. Its length divides a single application into a group of small services. Each service runs in its own independent process. Services coordinate and configure with each other to provide final value for users. Services communicate with each other through lightweight communication mechanism (HTTP), Each service is built around a specific business and can be independently deployed to the production environment. In addition, a unified and centralized service management mechanism should be avoided as far as possible. For a specific service, an appropriate language and tool (Maven) should be selected according to the business context, There can be a very lightweight centralized management to coordinate these services, services can be written in different languages, or different data stores.
The core of microservicing is to split the traditional one-stop application into one service according to the business and completely decouple it. Each microservice provides a service with a single business function. One service does one thing. From a technical point of view, it is a small and independent processing process. The concept of similar process can be started or destroyed independently, Have their own independent database.
- Microservices
It emphasizes the size of services. It focuses on a certain point. It is a service application that specifically solves a problem / provides landing corresponding services. In a narrow sense, it can be regarded as micro service projects in the idea or Moudel. IDEA
In the tool, independent small Moudel developed by Maven is used. It specifically uses a small module developed by SpringBoot. Professional things are done by professional modules, and each module does one thing. The emphasis is on individuals, and each individual completes a specific task or function.
- Microservice architecture
A new architecture form was proposed by Martin Fowler in 2014.
Microservice architecture is an architecture model. Its body length divides a single application into a group of small services. Services coordinate and cooperate with each other to provide final value for users. Each service runs in its own independent process, and lightweight communication mechanism = = (such as HTTP) is adopted between services to cooperate with each other. Each service is built around specific business and can be independently deployed to the production environment. In addition, unified and centralized service management mechanism should be avoided as far as possible. For a specific service, According to the business context, select the appropriate language and tool (such as Maven) = = to build it.
Advantages and disadvantages of microservices
advantage
The principle of single responsibility;
Each service is cohesive and small enough, and the code is easy to understand, so that it can focus on a specified business function or business requirement;
Development is simple and efficient. A service may be dedicated to only one thing;
Microservices can be developed independently by a small team, which only needs 2-5 developers;
Microservices are loosely coupled and functionally meaningful services, which are independent in the development stage or deployment stage;
Microservices can be developed in different languages;
It is easy to integrate with third parties. Microservices allow easy and flexible integration and automatic deployment through continuous integration tools, such as jenkins, Hudson and bamboo;
Microservices are easy to be understood, modified and maintained by a developer, so that small teams can pay more attention to their work results and reflect their value without cooperation;
Microservices allow the use and integration of the latest technologies;
Microservices are just business logic code and will not be mixed with HTML, CSS or other interfaces;
Each microservice has its own storage capacity. It can have its own database or a unified database;
shortcoming
Developers have to deal with the complexity of distributed systems;
Multi service operation and maintenance is difficult. With the increase of services, the pressure of operation and maintenance is also increasing; System deployment dependency;
Inter service communication cost;
Data consistency;
System integration test problems; Performance and monitoring issues;
1, Spring cloud getting started overview
Relationship between SpringCloud and SpringBoot
- SpringBoot focuses on the development of individual micro suits by KAISU
- SpringCloud is a microservice coordination and management framework that focuses on the overall situation. It integrates and manages individual microservices developed by SpringBoot, and provides integrated services among microservices: configuration management, service discovery, circuit breaker, routing, proxy, event stack, global lock, decision-making campaign, distributed session, etc;
- SpringBoot can be used independently of SpringCloud to develop projects, but SpringCloud is inseparable from SpringBoot and belongs to dependency relationship;
- SpringBoot focuses on the rapid and convenient development of individual micro services, and SpringCloud focuses on the global service governance framework
Dubbo and spring cloud technology selection
-
Distributed + service governance Dubbo
The current mature Internet architecture, application service splitting + message middleware -
Comparison between Dubbo and spring cloud
Take a look at community activity:
https://github.com/dubbo
https://github.com/spring-cloud
The biggest difference: Spring Cloud abandons Dubbo's RPC communication and adopts HTTP based REST
Strictly speaking, these two methods have their own advantages and disadvantages. Although to some extent, the latter sacrifices the performance of service calls, it also avoids the problems caused by the above-mentioned native RPC. Moreover, REST is more flexible than RPC. The dependence of service providers and callers only depends on a contract, and there is no strong dependence at the code level. This advantage is more appropriate in the current microservice environment that emphasizes rapid evolution.
Spring cloud Download
Official website: http://projects.spring.io/spring-cloud/
Self study reference books:
SpringCloud Netflix Chinese Documentation: https://springcloud.cc/spring-cloud-netflix.html
SpringCloud Chinese API document (official document translation): https://springcloud.cc/spring-cloud-dalston.html
SpringCloud China Community: http://springcloud.cn/
SpringCloud Chinese website: https://springcloud.cc
2, Use steps
Create project
CREATE TABLE `dept` ( `deptno` bigint NOT NULL AUTO_INCREMENT, `dname` varchar(255) NOT NULL, `dbsource` varchar(50) NOT NULL, PRIMARY KEY (`deptno`) ) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
Parent dependency
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.example</groupId> <artifactId>springcloud</artifactId> <version>1.0-SNAPSHOT</version> <modules> <module>springcloud-api</module> <module>springcloud-provider-8001</module> </modules> <properties> <project.build.sourEncoding>UTF-8</project.build.sourEncoding> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> </properties> <!-- Packaging method--> <packaging>pom</packaging> <dependencyManagement> <dependencies> <!-- springCloud rely on--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Hoxton.SR12</version> <type>pom</type> <scope>import</scope> </dependency> <!-- springBoot rely on--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>2.3.12.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> <!-- database--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.27</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.24</version> </dependency> <!-- mybatis starter--> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.2.0</version> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-core</artifactId> <version>1.2.10</version> </dependency> <!-- junit--> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.22</version> </dependency><!-- log4j--> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>2.12.1</version> </dependency> </dependencies> </dependencyManagement> </project>
springcloud-api
Interface
package com.my.pojo; import lombok.Data; import lombok.NoArgsConstructor; import lombok.experimental.Accessors; import java.io.Serializable; @Data @NoArgsConstructor @Accessors(chain = true)//Chain writing public class Dept implements Serializable {//Entity classes need to inherit serialization classes and database table mappings private Long deptno; private String dname; //It indicates which database the data exists in. A service corresponds to a database. The same information may be in different databases private String dbsource; public Dept(String dname) { this.dname = dname; } /* Dept =dept = new Dept(); dept.setDeptNo(11).setDname("sa").setDb_source("db01") */ }
pom
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>springcloud</artifactId> <groupId>org.example</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>springcloud-api</artifactId> <properties> <maven.compiler.source>8</maven.compiler.source> <maven.compiler.target>8</maven.compiler.target> </properties> <!-- current module Dependence on your own needs,If the parent dependency is already configured,You don't need to write--> <dependencies> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> </dependencies> </project>
springcloud-provider-8001 provider
pom
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>springcloud</artifactId> <groupId>org.example</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>springcloud-provider-8001</artifactId> <properties> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> </properties> <dependencies> <!-- Entity class required,to configure api module--> <dependency> <groupId>org.example</groupId> <artifactId>springcloud-api</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-core</artifactId> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> </dependency> <!-- test--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-test</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- jetty--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jetty</artifactId> </dependency> <!-- Hot deployment--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> </dependency> </dependencies> </project>
mybatis-config
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <settings> <!-- Enable L2 cache--> <setting name="cacheEnabled" value="true"/> </settings> </configuration>
application
server: port: 8001 #mybats configuration mybatis: type-aliases-package: com.my.pojo config-location: classpath:mybatis/mybatis-config.xml mapper-locations: classpath:mybatis/mapper/*.xml #spring configuration spring: application: name: springcloud-provider datasource: type: com.alibaba.druid.pool.DruidDataSource driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql//localhost:3306/db01?useUnicode=true&characterEncoding=utf-8 username: root password: 123456
Interface
DeptDao
import com.my.pojo.Dept; import org.apache.ibatis.annotations.Mapper; import org.springframework.stereotype.Repository; import java.util.List; @Mapper @Repository public interface DeptDao { public boolean addDept(Dept dept); public Dept queryById(Long id); public List<Dept> queryAll(); }
DeptService
import com.my.pojo.Dept; import java.util.List; public interface DeptService { public boolean addDept(Dept dept); public Dept queryById(Long id); public List<Dept> queryAll(); }
DeptServiceImpl
import com.my.dao.DeptDao; import com.my.pojo.Dept; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; @Service public class DeptServiceImpl implements DeptService{ @Autowired private DeptDao deptDao; @Override public boolean addDept(Dept dept) { return deptDao.addDept(dept); } @Override public Dept queryById(Long id) { return deptDao.queryById(id); } @Override public List<Dept> queryAll() { return deptDao.queryAll(); } }
DeptController
import com.my.pojo.Dept; import com.my.service.DeptService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import java.util.List; //Provide Restful services for external calls @RestController public class DeptController { @Autowired private DeptService deptService; @RequestMapping("/dept/add") public boolean add(@RequestBody Dept dept){ return deptService.addDept(dept); } @GetMapping("/dept/get/{id}") public Dept get(@PathVariable("id") Long id){ return deptService.queryById(id); } @GetMapping("/dept/list") public List<Dept> list(){ return deptService.queryAll(); } }
Startup class
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; //Startup class @SpringBootApplication public class DeptProvider_8001 { public static void main(String[] args) { SpringApplication.run(DeptProvider_8001.class,args); } }
Mapper
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.my.dao.DeptDao"> <insert id="addDept" parameterType="Dept"> insert into dept (dname,dbsource) values (#{dname},DATABASE()); </insert> <select id="queryById" parameterType="Long" resultType="Dept"> select * from dept where deptno = #{deptno}; </select> <select id="queryAll" resultType="Dept"> select * from dept ; </select> </mapper>
springcloud-consumer-80 consumer
Inject the rest template into the container through the configuration class. After injection, you can easily access the remote http service through the RestTemplate, providing a simple restful service template
rely on
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>springcloud</artifactId> <groupId>org.example</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>springcloud-consumer-80</artifactId> <properties> <maven.compiler.source>8</maven.compiler.source> <maven.compiler.target>8</maven.compiler.target> </properties> <!-- Consumers do not need to connect to the database, they only need entity classes and web--> <dependencies> <dependency> <groupId>org.example</groupId> <artifactId>springcloud-api</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- Hot deployment--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> </dependency> </dependencies> </project>
configuration file
server: port: 80
Configuration class
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.client.RestTemplate; @Configuration public class ConfigBean {//The configuration class is equivalent to ApplicationContext in Spring xml @Bean public RestTemplate getRestTemplate(){ return new RestTemplate(); } }
controller
import com.my.pojo.Dept; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.RestTemplate; import java.util.List; @RestController public class DeptConsumerController { //The consumer does not have a service layer //RestTemplate calls directly to inject the template into spring @Autowired private RestTemplate restTemplate;//Three parameters: url, entity and class //It provides a variety of convenient methods to access remote http services and a simple restful service template private static final String REST_URL_PREFIX ="http://localhost:8001"; // The url prefix requested by the provider is the same http://localhost:8001/dept/get?1 @RequestMapping("/con/get/{id}") public Dept get(@PathVariable("id") Long id){ //The request obtained in another module is get, so get is also used here return restTemplate.getForObject(REST_URL_PREFIX+"/dept/get/"+id,Dept.class); } @RequestMapping("/con/add") public boolean add(Dept dept){ //The request obtained in another module is get, so get is also used here return restTemplate.postForObject(REST_URL_PREFIX+"/dept/add",dept,Boolean.class); } @RequestMapping("/con/list") public List<Dept> list(){ //The request obtained in another module is get, so get is also used here return restTemplate.getForObject(REST_URL_PREFIX+"/dept/list",List.class); } }
Startup class
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class DeptConsumer_80 { public static void main(String[] args) { SpringApplication.run(DeptConsumer_80.class,args); } }
Provider startup
The function of this annotation is to encapsulate the passed json format string to the parameter where the annotation is located, provided that the attribute name in json is consistent with the attribute name in the parameter.