1. Ereka Cluster Construction
Cluster has two registry modules, which are spring-cloud-eureka-server-7001 and spring-cloud-eureka-server-7002.
Following is the construction of spring-cloud-eureka-server-7001, which is the same as spring-cloud-eureka-server-7002.
1.1 pom.xml configuration 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 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.6.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.mqb</groupId> <artifactId>spring-cloud-eureka-server-7001</artifactId> <version>0.0.1-SNAPSHOT</version> <name>spring-cloud-eureka-server-7001</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> <spring-cloud.version>Greenwich.SR2</spring-cloud.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
1.2 application.properties
server.port=7001 ##Registry will display domain name eureka.instance.hostname=eureka-server7001.com ##I don't register myself eureka.client.register-with-eureka=false ##Do not search for yourself in the registry eureka.client.fetch-registry=false ##Exposure address eureka.client.service-url.defaultZone=http://eureka-server7002.com:7002/eureka/
1.3 Main Startup Class
package com.mqb.eurekaserver7001; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; @SpringBootApplication @EnableEurekaServer public class SpringCloudEurekaServer7001Application { public static void main(String[] args) { SpringApplication.run(SpringCloudEurekaServer7001Application.class, args); } }
2. Two service providers
The names are spring-cloud-provider-8001 and spring-cloud-provider-8002, respectively.
Following is the construction of spring-cloud-provider-8001, which is the same as spring-cloud-provider-8002.
2.1 pom.xml 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 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.6.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.mqb</groupId> <artifactId>spring-cloud-provider-8001</artifactId> <version>0.0.1-SNAPSHOT</version> <name>spring-cloud-provider-8001</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> <spring-cloud.version>Greenwich.SR2</spring-cloud.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <!--mybatis Relevant--> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.1.0</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <!--Bean Relevant--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <!--ribbon Relevant--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-ribbon</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
2.2 application.properties
server.port=8001 ##mybatis path configuration. Note the use of config-locations between paths/ mybatis.mapper-locations=classpath:mapper/*.xml mybatis.type-aliases-package=classpath:com.mqb.provider8001.providerdept.entity ##Data Source Related Configuration spring.datasource.driver-class-name=com.mysql.jdbc.Driver spring.datasource.url=jdbc:mysql://localhost:3306/dept01?useSSL=false&serverTimezone=UTC&useUnicode=true&characterEncoding=utf8 spring.datasource.username=root spring.datasource.password=666666 ##The Registry will display the application name spring.application.name=provider ##Registry eureka.client.service-url.defaultZone=http://eureka-server7001.com:7001/eureka/,http://eureka-server7002.com:7002/eureka/
2.3 Main Class
package com.mqb.provider8001; import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; @SpringBootApplication @EnableEurekaClient @MapperScan("com.mqb.provider8001.providerdept.mapper") public class SpringCloudProvider8001Application { public static void main(String[] args) { SpringApplication.run(SpringCloudProvider8001Application.class, args); } }
2.4 DeptController.java
package com.mqb.provider8001.providerdept.controller; import com.mqb.provider8001.providerdept.entity.Dept; import com.mqb.provider8001.providerdept.service.DeptService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import javax.annotation.Resource; @Controller public class DeptController { private static final Logger log = LoggerFactory.getLogger(DeptController.class); @Resource private DeptService deptService; @RequestMapping("/getDept/{id}") @ResponseBody public Dept getDept(@PathVariable("id") Long deptId){ return deptService.getDeptById(deptId); } @RequestMapping("/deleteDept/{id}") @ResponseBody public boolean deleteDept(@PathVariable("id") Long deptId){ return deptService.deleteDeptById(deptId); } }
2.5 Dept.java
package com.mqb.provider8001.providerdept.entity; import lombok.Getter; import lombok.Setter; import lombok.ToString; @Setter @Getter @ToString public class Dept { private Long deptId; private String name; private String dbSource; }
2.6 DeptMapper.java
package com.mqb.provider8001.providerdept.mapper; import com.mqb.provider8001.providerdept.entity.Dept; import org.apache.ibatis.annotations.Result; import org.apache.ibatis.annotations.Results; import org.apache.ibatis.annotations.Select; public interface DeptMapper { int deleteByPrimaryKey(Long deptId); @Select("select * from dept where dept_id = #{deptId}") @Results({ @Result(column = "dept_id",property = "deptId"), @Result(column = "name",property = "name"), @Result(column = "db_source",property = "dbSource"), }) Dept selectByPrimaryKey(Long deptId); }
2.7 DeptService.java
package com.mqb.provider8001.providerdept.service; import com.mqb.provider8001.providerdept.entity.Dept; public interface DeptService { public Dept getDeptById(Long deptId); Boolean deleteDeptById(Long deptId); }
2.8 DeptServiceImpl.java
package com.mqb.provider8001.providerdept.service.impl; import com.mqb.provider8001.providerdept.entity.Dept; import com.mqb.provider8001.providerdept.mapper.DeptMapper; import com.mqb.provider8001.providerdept.service.DeptService; import org.springframework.stereotype.Service; import javax.annotation.Resource; @Service public class DeptServiceImpl implements DeptService { @Resource private DeptMapper deptMapper; @Override public Dept getDeptById(Long deptId) { return deptMapper.selectByPrimaryKey(deptId); } @Override public Boolean deleteDeptById(Long deptId) { return deptMapper.deleteByPrimaryKey(deptId) == 0?false:true; } }
3. Consumers (client s)
3.1 pom.xml 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 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.6.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.mqb</groupId> <artifactId>spring-cloud-consumer-8088</artifactId> <version>0.0.1-SNAPSHOT</version> <name>spring-cloud-consumer-8088</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> <spring-cloud.version>Greenwich.SR2</spring-cloud.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-ribbon</artifactId> </dependency> <!--getterh and setter Method--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
3.2 application.properties
server.port=8088 ##Microservice name spring.application.name=application-dept ##ribbon-related configuration eureka.client.register-with-eureka=false eureka.client.service-url.defaultZone=http://eureka-server7001.com:7001/eureka/,http://eureka-server7002.com:7002/eureka/
3.3 Main Class
package com.mqb.consumer8088; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; @SpringBootApplication @EnableEurekaClient public class SpringCloudConsumer8088Application { public static void main(String[] args) { SpringApplication.run(SpringCloudConsumer8088Application.class, args); } }
3.4 ConfigBean.java
restTemplate is used to achieve load balancing on the client side, requiring the @LoadBalanced annotation
package com.mqb.consumer8088.providerdept.config; import com.netflix.loadbalancer.IRule; import com.netflix.loadbalancer.RandomRule; import com.netflix.loadbalancer.RetryRule; import org.springframework.cloud.client.loadbalancer.LoadBalanced; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.client.RestTemplate; @Configuration public class ConfigBean { @Bean @LoadBalanced public RestTemplate getRestTemplate(){ return new RestTemplate(); } @Bean public IRule myRule(){ //Return new Random Rule ();//Random algorithm return new RetryRule();//If the service fails, skip polling next time. } }
3.5 DeptController_Consumer.java
package com.mqb.consumer8088.providerdept.controller; import com.mqb.consumer8088.providerdept.entity.Dept; 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 javax.annotation.Resource; @RestController public class DeptController_Consumer { private static final String REST_URL_PREFIX = "http://PROVIDER"; @Resource private RestTemplate restTemplate; @RequestMapping("/consumer/getDept/{id}") public Dept get(@PathVariable("id") long id){ Dept dept = restTemplate.getForObject(REST_URL_PREFIX+"/getDept/"+id,Dept.class); System.out.println(dept+"****deptId***"+dept.getDeptId()+"***name***"+dept.getName()); return dept; } @RequestMapping("/consumer/addDept") public boolean add(Dept dept){ return restTemplate.postForObject(REST_URL_PREFIX+"/addDept/",dept,boolean.class); } }
3.6 Dept.java
package com.mqb.consumer8088.providerdept.entity; import lombok.Getter; import lombok.Setter; import lombok.ToString; @ToString @Getter @Setter public class Dept { private Long deptId; private String name; private String dbSource; }
4. Building database
There are two databases, dept01 and dept02, which are used by spring-cloud-provider-8001 and spring-cloud-provider-8002 respectively. Each database contains a dept table. The following are the database and table statements for dept01. Dept02 is the same.
CREATE DATABASE `dept01` ; USE `dept01`; DROP TABLE IF EXISTS `dept`; CREATE TABLE `dept` ( `dept_id` bigint(20) NOT NULL AUTO_INCREMENT, `name` varchar(10) NOT NULL, `db_source` varchar(30) NOT NULL, PRIMARY KEY (`dept_id`) ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8; insert into `dept`(`dept_id`,`name`,`db_source`) values (1,'develop','dept01'),(2,'design','dept01'),(3,'sail','dept01');
Finally, the dept table under dept01 database is as follows:
The dept table under dept02 database is the same:
5. Testing
Before testing, you need to modify the host domain name mapping: open the hosts file under the C: Windows System32 drivers etc file and add the following two domain name mappings at the end of the file:
127.0.0.1 eureka-server7001.com 127.0.0.1 eureka-server7002.com
Start separately
spring-cloud-eureka-server-7001,
spring-cloud-eureka-server-7002,
spring-cloud-provider-8001,
spring-cloud-provider-8001,
spring-cloud-consumer-8088
Enter eureka-server 7001.com:7001 in the browser address bar and return to the following interface. Enter eureka-server 7001.com:7002.
Open a new interface, then enter in the address bar: http://localhost:8088/consumer/getDept/1 Fig. 1 results are obtained after return, Fig. 2 results are refreshed, and Fig. 1 results are obtained after refreshing. This is the polling algorithm used by ribbon by default. Polling accesses two modules that provide the same service.