1, Service provider and service consumer
noun | definition |
Service provider | The callee of the service (that is, the service that provides services to other services) |
Service consumers | The caller of the service (that is, the service that depends on other services) |
2, Write service provider
2.1 pom.xml
<?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.yuxx.cloud</groupId> <artifactId>microservice-simple-provider-user</artifactId> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging> <!--Spring Boot--> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.2.6.RELEASE</version> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <java.version>1.8</java.version> </properties> <dependencies> <!--provide Spring MVC Support for--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--provide Spring Data JPA Support for--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> </dependency> </dependencies> <!--introduce Spring Cloud Dependence on--> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Edgware.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <!--add to spring-boot Of maven plug-in unit--> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
2.2 table creation statement
drop table user if exists; create table user( id bigint generated by default as identity, username varchar(40), name varchar (20), age int(3), balance decimal (10,2), primary key(id) );
2.3 table data
insert into user(id,username,name,age,balance) values(1,'account1','Zhang San',20,100.00); insert into user(id,username,name,age,balance) values(2,'account2','Li Si',28,180.00); insert into user(id,username,name,age,balance) values(3,'account3','Wang Wu',32,280.00);
2.4 user entity class
package com.yuxx.cloud.entity; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import javax.persistence.*; import java.math.BigDecimal; @Entity @JsonIgnoreProperties(value = { "hibernateLazyInitializer", "handler" }) public class User { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; @Column private String username; @Column private String name; @Column private Integer age; @Column private BigDecimal balance; //...Setter and Getter }
2.5 DAO
package com.yuxx.cloud.dao; import com.yuxx.cloud.entity.User; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; @Repository public interface UserRepository extends JpaRepository<User,Long> { }
2.6 Controller
package com.yuxx.cloud.controller; import com.yuxx.cloud.dao.UserRepository; import com.yuxx.cloud.entity.User; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController; @RestController public class UserController { @Autowired private UserRepository userRepository; @GetMapping("/{id}") public User findById(@PathVariable Long id){ User user = userRepository.getOne(id); return user; } }
2.7 startup
package com.yuxx.cloud; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class ProviderUserApplication { public static void main(String[] args) { SpringApplication.run(ProviderUserApplication.class,args); } }
2.8 configuration file
2.9 testing
Browser access http://localhost:8000/1, results obtained:
3, Write service consumer
3.1 pom file
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.yuxx.cloud</groupId> <artifactId>microservice-simple-consumer-movie</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <!--Spring Boot--> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.2.6.RELEASE</version> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> </dependency> </dependencies> <!--introduce Spring Cloud Dependence on--> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Edgware.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <!--add to spring-boot Of maven plug-in unit--> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
3.2 user entity class
package com.yuxx.cloud.entity; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import javax.persistence.*; import java.math.BigDecimal; public class User { private Long id; private String username; private String name; private Integer age; private BigDecimal balance; //Setter and Getter }
3.3 startup
package com.yuxx.cloud; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; import org.springframework.web.client.RestTemplate; @SpringBootApplication public class ConsumerMovieApplication { public static void main(String[] args) { SpringApplication.run(ConsumerMovieApplication.class, args); } @Bean public RestTemplate restTemplate(){ return new RestTemplate(); } }
3.4 Controller
package com.yuxx.cloud.controller; import com.yuxx.cloud.entity.User; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.RestTemplate; @RestController public class MovieController { @Autowired private RestTemplate restTemplate; @GetMapping("user/{id}") public User findById(@PathVariable Long id){ return restTemplate.getForObject("http://localhost:8000/" + id,User.class); } }
3.5 configuration file
server: port: 8010
3.6 test visit
4, Integrating spring boot activator
Endpoint | describe | HTTP method | Sensitive or not |
autoconfig | Display auto configuration information | GET | yes |
beans | Show all spring beans in the application context | GET | |
configprops | Display the list of configuration properties for all @ ConfigurationProperties | GET | yes |
dump | Show a snapshot of thread activity | GET | yes |
env | Display the environment variables of the application | GET | yes |
health | Displays the health indicators for the application, which are provided by the health indicator's implementation class. When the application turns on security protection, only simple status will be displayed for the request without user authentication; if it is authenticated, the health details will be displayed. | GET | no |
info | Display the application information. You can use the info. * property to customize the data exposed by the info endpoint | GET | no |
mappings | Display the path list of all @ RequestMapping | GET | yes |
metrics | Show applied metrics information | GET | yes |
shutdown | Close the application (not enabled by default. If you want to enable it, you need to set end-points.shutdown.enabled=true ) | POST | yes |
trace | Display trace information (100 HTTP requests by default) | GET | yes |
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>
management: security: enabled: false
In Spring Boot 2.x, activator only opens the health and info endpoints by default. 1.x view detailed data configuration mode is deprecated. To view the detailed data of health port, you can configure it as follows:
management: endpoint: health: show-details: always
Access via browser: http://localhost : 8000 / Actor / health, or the result is similar to the following:
Visit: http://localhost:8000/actuator/info , you can see the following:
It can be seen from the results that the info port did not return any data to us. You can use the info. * property to define the data exposed by the info port:
info: app: name: @project.artifactId@ encoding: @project.build.sourceEncoding@ java: source: @java.version@ target: @java.version@
After restart, visit again: http://localhost:8000/actuator/info , you will see something similar to the following:
5, What are the problems of hard coding
user: userServiceUrl: http://localhost:8000/
The movicontroller code is changed to:
@Value("${user.userServiceUrl}") private String userServiceUrl; @GetMapping("user/{id}") public User findById(@PathVariable Long id){ return restTemplate.getForObject(userServiceUrl + id,User.class); }
- Limited use scenarios
If the network address (IP and port) of the service provider changes, it will affect the service consumer. For example, if the network address of the user's microservice changes, it is necessary to modify the configuration of the movie microservice and republish it, which is obviously not desirable. - Unable to scale dynamically
In the production environment, each microservice will generally deploy multiple instances to achieve disaster recovery and load balancing. In the system of microservice architecture, it also needs the ability of automatic scaling, such as dynamic increase and decrease of nodes. Hard coding can't meet this demand.