Ereka Cluster and ribbon Load Balancing Build Quickly

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.

 

Keywords: Spring Maven Java Apache

Added by d00dle on Wed, 31 Jul 2019 09:49:39 +0300