整体架构图:

1. eureka集群搭建

集群有两个注册中心模块,模块名分别是:spring-cloud-eureka-server-7001和spring-cloud-eureka-server-7002

以下介绍spring-cloud-eureka-server-7001的搭建,spring-cloud-eureka-server-7002同理。

1.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>
	<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

##注册中心会显示域名
eureka.instance.hostname=eureka-server7001.com
##自己不注册自己
eureka.client.register-with-eureka=false
##不在注册中心查找自己
eureka.client.fetch-registry=false
##对外暴露地址
eureka.client.service-url.defaultZone=http://eureka-server7002.com:7002/eureka/

1.3 主启动类

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. 服务提供者两个

分别名称分别是:spring-cloud-provider-8001和spring-cloud-provider-8002

以下只介绍spring-cloud-provider-8001的搭建,spring-cloud-provider-8002同理

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>
	<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相关-->
		<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相关-->
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<optional>true</optional>
		</dependency>

		<!--ribbon相关-->
		<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路径配置。注意config-locations路径之间用/
mybatis.mapper-locations=classpath:mapper/*.xml
mybatis.type-aliases-package=classpath:com.mqb.provider8001.providerdept.entity

##数据源相关配置
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

##注册中心会显示该应用名
spring.application.name=provider
##注册中心
eureka.client.service-url.defaultZone=http://eureka-server7001.com:7001/eureka/,http://eureka-server7002.com:7002/eureka/

2.3 主类

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. 消费者(client):spring-cloud-consumer-8088

3.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>
	<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和setter方法-->
		<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

##微服务名
spring.application.name=application-dept
        
##ribbon相关配置
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 主类

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用于实现客户端的负载均衡,需要加@LoadBalanced注解

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 RandomRule(); //随机算法
        return new RetryRule();//发现服务失败,下次跳过该服务的轮询。
    }
}

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. 建数据库

一共两个数据库分别是dept01和dept02,分别被spring-cloud-provider-8001和spring-cloud-provider-8002使用,每个数据库包含一个dept表。以下是dept01的见数据库和建表语句。dept02同理。


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');

最后dept01数据库下的dept表如下:

dept02数据库下的dept表同理:

5. 测试

测试前还需要修改host域名映射:打开 C:\Windows\System32\drivers\etc文件下的hosts文件,在文件末尾添加如下两个域名映射:

127.0.0.1   eureka-server7001.com 

127.0.0.1   eureka-server7002.com

分别启动

spring-cloud-eureka-server-7001,

spring-cloud-eureka-server-7002,

spring-cloud-provider-8001,

spring-cloud-provider-8001,

spring-cloud-consumer-8088

在浏览器地址栏输入: eureka-server7001.com:7001回车返回如下界面。输入eureka-server7001.com:7002同理。

新打开一个界面,接下来在地址栏输入:http://localhost:8088/consumer/getDept/1,按回车后得到下面图一结果,刷新得到图二结果,再刷新又得到图一结果......这就是ribbon默认使用的轮询算法。轮询的访问两个提供相同服务的模块。

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐