springcloud-02-基本用法-Eureka服务发现与注册及面试题型

本文介绍了SpringCloud中Eureka的基本用法,包括创建Eureka服务注册模块、服务提供者和服务消费者的过程。讲解了Eureka集群配置,强调了在hosts文件中添加映射的重要性。此外,还探讨了Eureka与Zookeeper在服务注册中心角色上的区别,指出Eureka遵循的是AP原则,更注重高可用性。
摘要由CSDN通过智能技术生成

按照下图创建工程:

首先先创建一个工作集,方便项目管理,在工作集下面创建分布式集群项目。这里有个工程名命名规范,参照工程名图的命名规范,这样方便管理。
工程名图
微服务架构图

创建父工程:

  1. 创建一个maven空项目的父工程,注意这里的父工程是pom类型的,图1所示,在按照图2步骤创建。图3是创建父工程的操作步骤,在父工程里主要定义版本信息,供它的子模块使用,父工程如果定义了一些依赖的版本信息,那么它的子模块只需要添加依赖就行了,不需要写版本信息,父工程里没有的依赖或者没有定义的依赖版本信息,子模块又需要用的话,可以在子模块里自己定义版本信息和添加依赖,
    图1
    图2
    图3
<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>com.lyj.springcloud</groupId>
	<artifactId>microservicecloud</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>pom</packaging>
	<!-- 新建父工程microservicecloud,切记是packageing是pom模式 主要是定义pom文件,将后续的各个子模块公用的jar包统一提出来, 
		类似一个抽象父类 -->
	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<!--指定每次编译的时候都是以java8版本进行编译 ====start -->
		<maven.compiler.source>1.8</maven.compiler.source>
		<maven.compiler.target>1.8</maven.compiler.target>
		<!--指定每次编译的时候都是以java8版本进行编译 ====end -->
		<junit.version>4.12</junit.version>
		<log4j.version>1.2.17</log4j.version>
		<lombok.version>1.16.18</lombok.version>
	</properties>

	<dependencyManagement>

		<dependencies>
			<dependency>
				<groupId>org.springframework.cloud</groupId>
				<artifactId>spring-cloud-dependencies</artifactId>
				<version>Dalston.SR1</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
			<dependency>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-dependencies</artifactId>
				<version>1.5.9.RELEASE</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
			<dependency>
				<groupId>mysql</groupId>
				<artifactId>mysql-connector-java</artifactId>
				<version>5.0.4</version>
				<scope>runtime</scope>
			</dependency>
			<dependency>
				<groupId>com.alibaba</groupId>
				<artifactId>druid</artifactId>
				<version>1.0.31</version>
			</dependency>
			<dependency>
				<groupId>org.mybatis.spring.boot</groupId>
				<artifactId>mybatis-spring-boot-starter</artifactId>
				<version>1.3.0</version>
			</dependency>
			<dependency>
				<groupId>ch.qos.logback</groupId>
				<artifactId>logback-core</artifactId>
				<version>1.2.3</version>
			</dependency>

			<dependency>
				<groupId>junit</groupId>
				<artifactId>junit</artifactId>
				<version>${junit.version}</version>
			</dependency>
			<dependency>
				<groupId>log4j</groupId>
				<artifactId>log4j</artifactId>
				<version>${log4j.version}</version>
			</dependency>


		</dependencies>
	</dependencyManagement>
	<build>
	<!-- 这里的 配置是使在Eureka的web界面能够访问服务的info界面(服务的详细信息)==start -->
	<!-- finalName指父工程的名字 -->
		<finalName>microservicecloud</finalName>
		<!-- resources:资源,允许你访问的资源 
		directory:允许你访问这个路径下的资源
		filtering:访问过滤开启-->
		<resources>
			<resource>
				<directory>src/main/resources</directory>
				<filtering>true</filtering>
			</resource>
		</resources>
		<plugins>
		<!-- plugins:引入插件的意思,
		 <groupId>org.apache.maven.plugins</groupId>
		<artifactId>maven-resources-plugin</artifactId>
				上面的插件是负责解析和解读的-->
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-resources-plugin</artifactId>
				<!-- configuration:解析配置的意思,
				 <delimiter>$</delimiter>:意思就是以$开头和以$结尾的
				 在<directory>src/main/resources</directory>路径下面
				 的信息,我就能读取,即要显示的信息-->
				<configuration>
					<delimiters>
						<delimiter>$</delimiter>
					</delimiters>
				</configuration>
			</plugin>

		</plugins>
<!-- 这里的 配置是使在Eureka的web界面能够访问服务的info界面(服务的详细信息)==end -->
	</build>




	<!-- 创建microservice-api服务,自动在父工程pom文件里引进module配置 -->
	<modules>
		<module>microservicecloud-api</module>
		<module>microservicecloud-provider-dept-8001</module>
		<module>microservicecloud-consumer-dept-80</module>
		<module>microservicecloud-eureka-7001</module>
		<module>microservicecloud-eureka-7002</module>
		<module>microservicecloud-eureka-7003</module>
	</modules>
</project>

创建公共子模块(Module):

除了父工程是pom类型的工程,后面的公共子模块和服务提供者工程和服务消费者工程都是jar包类型。并且创建都是在父工程下创建module模块,创建完成后检查父工程中的pom文件是否添加了创建的module,如果自动添加了,则创建正确。

<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>
  <!-- 本Module开发步骤
  		1、新建microservicecloud-api创建完成后查看pom文件变化
  		2、修改pom
  		3、新建Entity且配合lombok使用
  		4、mvn clean&install(打成jar包)后给其他模块引用,达到通用的目的。
  		   也即需要用到部门实体的话,不用每个工程都定义一份,直接引用本模块即可  -->
  <parent>
  <!-- 子类里面显示声明才能有明确的继承表现,
   无意外就是父类的默认版本否则自己定义-->
    <groupId>com.lyj.springcloud</groupId>
    <artifactId>microservicecloud</artifactId>
    <version>0.0.1-SNAPSHOT</version>
  </parent>
  <!-- 当前Module,就是我自己叫什么名字 -->
  <artifactId>microservicecloud-api</artifactId>
  
  <!-- 当前Module需要用的jar包,按自己需求添加,
  入股父类已经包含了,可以不用 写版本号-->
  <dependencies>
  <dependency>
  <groupId>org.projectlombok</groupId>
  <artifactId>lombok</artifactId>
  </dependency>
  </dependencies>
</project>

这里添加了一个lombok依赖主要是用来简化和方便写我们的Javabean,添加这个依赖,可以不用写getter和setter方法、构造方法、toString()等。直接在相应的Javabean上面添加相应的注解即可。

图4是公共子模块的架构图:
图4
在这里创建了一个公共的Javabean,供后面服务提供者和服务消费者使用。如下:

package com.lyj.springcloud.entities;

import java.io.Serializable;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
@SuppressWarnings("serial")//如果有类上或者方法上或者参数上有警告。添加此注解可以选择压制
//@AllArgsConstructor//添加传参构造函数的注解,依赖于lombok(俗称小辣椒)的依赖
@NoArgsConstructor//添加构造空构造函数的注解
@Data//添加使每个参数都生成getter和setter方法
@Accessors(chain=true)//添加链式风格访问的注解
public class Dept implements Serializable//Dept(Entity)  ORM mysql->Dept(table)  类关系映射
{		//必须序列化
	
	private Long 	deptno;//主键

	private String 	dname;//部门名称

	/**
	 * 来自哪个数据库,因为微服务架构可以一个服务对应一个数据库,
	 * 同一个信息被存在不同的数据库
	 */

	private String 	db_source;

	
//	检测是否能够自定义构造函数
//	public Dept(String dname) {
//		super();
//		this.dname = dname;
//	}
//	
//	//检测链式风格访问是否起作用
//	public static void main(String[] args) {
//		Dept dept=new Dept();
		这里下面是检测
//		dept.setDeptno(11l).setDname("RD").setDb_source("DB01");
//	}
	

}

创建服务注册模块(cloud-server):

架构图5:
图5
pom.xml配置:

<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>com.lyj.springcloud</groupId>
		<artifactId>microservicecloud</artifactId>
		<version>0.0.1-SNAPSHOT</version>
	</parent>
	<groupId>microservicecloud</groupId>
	<artifactId>microservicecloud-eureka-7001</artifactId>

	<dependencies>
		<!-- eureka-server服务端配置 -->
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-eureka-server</artifactId>
		</dependency>
		<!-- 修改后立即生效,热部署 ===start-->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>springloaded</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-devtools</artifactId>
		</dependency>
		<!--修改后立即生效,热部署===end-->
	</dependencies>

</project>

创建application主程序:
记得在主程序上添加@EnableEurekaServer注解,开启服务,用来接收服务的注册。

package com.lyj.springcloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@SpringBootApplication
@EnableEurekaServer // Eureka服务器端启动类,接收其他微服务注册进来
public class EurekaServer7001_App {

    public static void main(String[] args) {
        SpringApplication.run(EurekaServer7001_App.class, args);
    }

}

创建application.yml文件:

单机版的Eureka配置
server:
  port: 7001

eureka:
#  server:
#    enable-self-preservation: false #禁用自我保护机制
  instance:
    hostname: localhost #eureka服务端的实例名称
  client:
    register-with-eureka: false #false 表示不向注册中心注册自己
     #false表示自己就是注册中心,我的职责就是维护服务实例,并不需要去检索服务
    fetch-registry: false
    service-url:
    #设置与Eureka Server交互的地址查询服务和注册服务都需要这个地址
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
    

创建服务提供者工程

服务提供者开发流程图:
在这里插入图片描述
架构图:
在这里插入图片描述
配置pom文件如下:

<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>com.lyj.springcloud</groupId>
		<artifactId>microservicecloud</artifactId>
		<version>0.0.1-SNAPSHOT</version>
	</parent>
	<artifactId>microservicecloud-provider-dept-8001</artifactId>
	<dependencies>
		<!-- 引入自定义的api通用包,可以使用Dept部门的Entity -->
		<dependency>
			<groupId>com.lyj.springcloud</groupId>
			<artifactId>microservicecloud-api</artifactId>
			<!-- 下面指定的版本是活的,相当于,api通用包随意怎么变,这里都会自动更新,不影响 -->
			<version>${project.version}</version>
		</dependency>
		<!-- 将微服务注册provider到Eureka注册中心中 ==start -->
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-eureka</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-config</artifactId>
		</dependency>
		<!-- 将微服务注册provider到Eureka注册中心中 ==end -->
		<!-- 引入监控信息完善的依赖==start -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-actuator</artifactId>
		</dependency>
		<!-- 引入监控信息完善的依赖==end -->
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
		</dependency>
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<scope>runtime</scope>
		</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>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-jetty</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
		</dependency>
		<!-- 引入热部署,修改后立即生效===start -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>springloaded</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-devtools</artifactId>
		</dependency>
		<!-- 引入热部署,修改后立即自动发布和构建生效===end -->
	</dependencies>


</project>

配置application.yml 文件:

server:
#指定服务器端口号8001
  port: 8001
  
mybatis:
#mybatis配置文件所在路径
  config-location: classpath:mybatis/mybatis.cfg.xml
   #所有Entity别名类所在包
  type-aliases-package: com.lyj.springcloud.entities
   #mapper映射文件所在路径
  mapper-locations:
  - classpath:mybatis/mapper/**/*.xml
  
spring:
  application:
   # 当前应用(服务)起的名字
    name: microservicecloud-dept       
  datasource:
  #当前数据源操作类型
    type: com.alibaba.druid.pool.DruidDataSource
    #mysql驱动包
    driver-class-name: com.mysql.jdbc.Driver
     #数据库名称
    url: jdbc:mysql://localhost:3306/cloudDB01
    username: mysql
    password: 15827318595
    dbcp2: 
       min-idle: 5        #数据库连接池的最小维持连接数
       initial-size: 5    #初始化连接数5个
       max-total: 5       #设置最大连接数
       max-wait-millis: 200  #s等待连接获取的最大超时时间
      

#配置Eureka
eureka:
#客户端注册进Eureka服务列表内
  client:
    service-url:
      defaultZone: http://localhost:7001/eureka #(单机版服务器)

服务提供者详细架构图如下:
服务提供者架构图

  1. 创建DeptDao访问数据库的接口:
package com.lyj.springcloud.dao;

import java.util.List;

import org.apache.ibatis.annotations.Mapper;

import com.lyj.springcloud.entities.Dept;

@Mapper // 添加mybatis注解(mapper文件)
public interface DeptDao {

    public boolean addDept(Dept dept);

    public Dept findById(Long id);

    public List < Dept > findAll();
}

  1. 创建DeptService接口:
package com.lyj.springcloud.service;

import java.util.List;

import com.lyj.springcloud.entities.Dept;

public interface DeptService {

    /**
     * 这里是对数据库访问的函数,比较靠近底层,为了比较符合rest的风格, 这里的函数名都是以靠近底层的命名方式命名
     * 
     * @param dept
     * @return
     */
    public boolean add(Dept dept);

    public Dept get(Long id);

    public List < Dept > list();
}

  1. 创建接口实现类DeptServiceImpl:
package com.lyj.springcloud.service.impl;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.lyj.springcloud.dao.DeptDao;
import com.lyj.springcloud.entities.Dept;
import com.lyj.springcloud.service.DeptService;

@Service("deptService")
public class DeptServiceImpl implements DeptService {
    @Autowired
    private DeptDao deptDao;

    @Override
    public boolean add(Dept dept) {

        return deptDao.addDept(dept);
    }

    @Override
    public Dept get(Long id) {

        return deptDao.findById(id);
    }

    @Override
    public List < Dept > list() {

        return deptDao.findAll();
    }

}

  1. 创建控制器:
package com.lyj.springcloud.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import com.lyj.springcloud.entities.Dept;
import com.lyj.springcloud.service.DeptService;

@RestController
public class DeptController {

    @Autowired
    private DeptService service;

    /**
     * 这里是引入服务发现的DiscoveryClient 注意这里的DiscoveryClient是引用这个 org.springframework.cloud.client.discovery.DiscoveryClient;
     * 还需要在application的主程序中添加@EnableDiscoveryClient注解,开启服务发现功能
     */
    @Autowired
    private DiscoveryClient client;

    @RequestMapping(value = "/dept/add", method = RequestMethod.POST)
    public boolean add(@RequestBody Dept dept) {

        return service.add(dept);
    }

    @RequestMapping(value = "/dept/get/{id}", method = RequestMethod.GET)
    public Dept get(@PathVariable("id") Long id) {

        return service.get(id);
    }

    @RequestMapping(value = "/dept/list", method = RequestMethod.GET)
    public List < Dept > list() {

        return service.list();
    }

    @RequestMapping(value = "/dept/discovery", method = RequestMethod.GET)
    public Object discovery() {
        List < String > list = client.getServices();
        System.out.println("************" + list);

        List < ServiceInstance > srvList = client.getInstances("MICROSERVICECLOUD-DEPT");
        for (ServiceInstance eInstance : srvList) {
            System.out.println(eInstance.getServiceId() + "\t" + eInstance.getHost() + "\t" + eInstance.getPort() + "\t"
                    + eInstance.getUri());
        }
        return this.client;
    }

}

  1. 创建application主程序 这里面配置了服务发现(服务发现用用的不多,主要是服务注册)
package com.lyj.springcloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

@EnableDiscoveryClient // 开启服务发现功能,控制器里的服务发现方法能正常运行。
@EnableEurekaClient // 本服务启动后会自动将服务注册进Eureka服务中心中
@SpringBootApplication
public class DeptProvider8001_App {

    /**
     * 使用服务发现功能步骤: 1、先要启动EurekaServer 2、再启动DeptProvider8001_App主启动类,需要 稍等一会 3、访问http://localhost:8001/dept/discovery
     * 
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub

        SpringApplication.run(DeptProvider8001_App.class, args);

    }

}

下图是数据访问的路径,mapper.xml文件路径:
在这里插入图片描述
配置DeptMapper.xml文件:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.lyj.springcloud.dao.DeptDao">
	<select id="findById" resultType="Dept" parameterType="Long">
		select deptno dname,db_source from dept where deptno=#{deptno};
	</select>
	<select id="findAll" resultType="Dept">
		select deptno,dname,db_source from dept;
	</select>
	<insert id="addDept" parameterType="Dept">
		<!-- database()mysql自带的查询数据源的名字的()数据库的名字 -->
		INSERT INTO dept(dname,db_source) VALUES(#{dname},DATABASE());
	</insert>

</mapper>

配置mybatis.cfg.xml,这里可有可无,主要配置一些访问数据库的一些属性缓存之类的。如下:

<?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>
        <setting name="cacheEnabled" value="true"/><!-- 二级缓存开启 -->
    </settings>
</configuration>

服务消费者配置:

服务消费者的开发流程图:
在这里插入图片描述
架构图:
在这里插入图片描述
pom文件配置:

<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>com.lyj.springcloud</groupId>
		<artifactId>microservicecloud</artifactId>
		<version>0.0.1-SNAPSHOT</version>
	</parent>
	<artifactId>microservicecloud-consumer-dept-80</artifactId>
	<description>部门微服务消费者</description>

	<dependencies>
	<!-- 引入自己定义的api -->
		<dependency>
			<groupId>com.lyj.springcloud</groupId>
			<artifactId>microservicecloud-api</artifactId>
			<version>${project.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<!-- 引入热部署,修改后立即生效===start -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>springloaded</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-devtools</artifactId>
		</dependency>
		<!-- 引入热部署,修改后立即自动发布和构建生效===end -->

	</dependencies>
</project>

配置application.yml文件

server:
  port: 80  #访问时不用加端口号,因为浏览器的默认端口就是80,所以访问:localhosst/xxxxx

创建application主程序:

package com.lyj.springcloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DeptConsumer80_App {

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        SpringApplication.run(DeptConsumer80_App.class, args);
    }

}

创建Config.java 文件:

package com.lyj.springcloud.cfgbeans;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

@Configuration
public class ConfigBean {
    @Bean
    public RestTemplate geRestTemplate() {
        return new RestTemplate();
    }

}
// boot--spring applicationContext.xml
//--@Configuration配置 ConfigBean=applicationContext.xml
//public UserService getUserService() {
//  return new UserServiceImpl();
//}
/**
 * applicationContext.xml==ConfigBean(@Configuration) <bean id="userService" class="com.lyj.tmall.UserServiceImpl">
 * 这里的id相当于上面的方法类型UserService,class就相当于return的返回值,
 */

创建控制器:

package com.lyj.springcloud.controller;

import java.util.List;

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 com.lyj.springcloud.entities.Dept;

@RestController
public class DeptController_consumer {
    /**
     * RestTemplate提供了多种便捷访问远程Http服务的方法, 是一种简单便捷的访问restful服务模板类, 是spring提供的用于访问Rest服务的客户端模板工具集 用法:
     * 使用restTemplate访问restful接口非常的简单粗暴无脑。 (url,requestMap,ResponseBean.class)这三个参数分别代表 REST请求地址、请求参数、HTTP响应转换被转换成的对象类型。
     *
     */
    @Autowired
    private RestTemplate restTemplate;

    private static final String TEST_URL_PREFIX = "http://localhost:8001";

    @RequestMapping(value = "/consumer/dept/add")
    public boolean add(Dept dept) {
        return restTemplate.postForObject(TEST_URL_PREFIX + "/dept/add", dept, boolean.class);
//        return restTemplate.getForObject(TEST_URL_PREFIX + "/dept/add", boolean.class, dept);

    }

    @RequestMapping(value = "/consumer/dept/get/{id}")
    public Dept get(@PathVariable("id") Long id) {
        return restTemplate.getForObject(TEST_URL_PREFIX + "/dept/get/" + id, Dept.class);
    }

    @SuppressWarnings("unchecked")
    @RequestMapping(value = "/consumer/dept/list")
    public List < Dept > list(Dept dept) {
        return restTemplate.getForObject(TEST_URL_PREFIX + "/dept/list", List.class);
    }

    // 测试@EnableDiscoveryClient,消费者可以调用服务发现,消费者的application主程序不用添加@EnableDiscoveryClient
    @RequestMapping(value = "/consumer/dept/discovery")
    public Object discovery() {
        return restTemplate.getForObject(TEST_URL_PREFIX + "/dept/discovery", Object.class);
    }

}

数据库执行脚本:

-- drop database if exists cloudDB01;
CREATE DATABASE cloudDB01 CHARACTER SET UTF-8;
USE cloudDb01;
CREATE TABLE dept
( 
   deptno BIGINT NOT NULL PRIMARY KEY AUTO_INCREMENT,
   dname VARCHAR(60),
   db_source VARCHAR(60)
);
-- DATABASE()查询获取当前数据源(数据库)的名字
INSERT INTO dept(dname,db_source) VALUES('开发部',DATABASE());
INSERT INTO dept(dname,db_source) VALUES('人事部',DATABASE());
INSERT INTO dept(dname,db_source) VALUES('市场部',DATABASE());
INSERT INTO dept(dname,db_source) VALUES('运维部',DATABASE());
SELECT * FROM dept;   

INSERT INTO dept(dname,db_source) VALUES(123,DATABASE());

测试:
在这里插入图片描述
一上操作都是一个Eureka-server服务器的运行。
下面讲一下集群分布式开发:

集群开发步骤:

Eureka集群开发流程图:

在这里插入图片描述
集群配置,也就是服务消费者不动,只用增加服务器子模块的配置的数量即可。在父工程下创建服务器工程子模块
如下:
架构图:在这里插入图片描述
配置7002工程和7003工程的pom文件,与7001pom文件一样,直接copy过来。pom文件如下:

<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>com.lyj.springcloud</groupId>
    <artifactId>microservicecloud</artifactId>
    <version>0.0.1-SNAPSHOT</version>
  </parent>
  <artifactId>microservicecloud-eureka-7002</artifactId>
  
<dependencies>
		<!-- eureka-server服务端配置 -->
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-eureka-server</artifactId>
		</dependency>
		<!-- 修改后立即生效,热部署 -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>springloaded</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-devtools</artifactId>
		</dependency>
	</dependencies>

</project>

修改7002工程和7003工程的application主程序配置:
主程序配置一样,只不过类名不一样而已

package com.lyj.springcloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@SpringBootApplication
@EnableEurekaServer // Eureka服务器端启动类,接收其他微服务注册进来
public class EurekaServer7002_App {

    public static void main(String[] args) {
        SpringApplication.run(EurekaServer7002_App.class, args);
    }

}

修改7001工程的application.yml配置文件,改为集群配置:

#单机版的Eureka配置
#server:
#  port: 7001
#
#eureka:
##  server:
##    enable-self-preservation: false #禁用自我保护机制
#  instance:
#    hostname: localhost #eureka服务端的实例名称
#  client:
#    register-with-eureka: false #false 表示不向注册中心注册自己
#     #false表示自己就是注册中心,我的职责就是维护服务实例,并不需要去检索服务
#    fetch-registry: false
#    service-url:
#    #设置与Eureka Server交互的地址查询服务和注册服务都需要这个地址
#      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
#    

#集群Eureka配置,即把相同的服务部署到不同的服务器上运行,避免由于一台服务器异常而终止程序,
#集群配置可以在一台服务器发生异常的情况下,还能保持程序的正常运行
server:
  port: 7001

eureka:
#  server:
#    enable-self-preservation: false #禁用自我保护机制
  instance:
    hostname: eureka7001.com #eureka服务端的实例名称
  client:
    register-with-eureka: false #false 表示不向注册中心注册自己
     #false表示自己就是注册中心,我的职责就是维护服务实例,并不需要去检索服务
    fetch-registry: false
    service-url:
#      defaultZone: http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/ 
      defaultZone: http://eureka7002.com:7002,http://eureka7003.com:7003
    
    #设置与Eureka Server交互的地址查询服务和注册服务都需要这个地址
#      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/  #(单机)
#      defaultZone: http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
    
    
    

7002application.yml文件配置:

#集群Eureka配置,即把相同的服务部署到不同的服务器上运行,避免由于一台服务器异常而终止程序,
#集群配置可以在一台服务器发生异常的情况下,还能保持程序的正常运行
server:
  port: 7002

eureka:
#  server:
#    enable-self-preservation: false #禁用自我保护机制
  instance:
    hostname: eureka7002.com #eureka服务端的实例名称
  client:
    register-with-eureka: false #false 表示不向注册中心注册自己
     #false表示自己就是注册中心,我的职责就是维护服务实例,并不需要去检索服务
    fetch-registry: false
    service-url:
    #设置与Eureka Server交互的地址查询服务和注册服务都需要这个地址
#      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/  #(单机)
#      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7003.com:7003/eureka/
      defaultZone: http://eureka7001.com:7001,http://eureka7003.com:7003
 
    

7003application.yml文件配置:

#集群Eureka配置,即把相同的服务部署到不同的服务器上运行,避免由于一台服务器异常而终止程序,
#集群配置可以在一台服务器发生异常的情况下,还能保持程序的正常运行
server:
  port: 7003

eureka:
#  server:
#    enable-self-preservation: false #禁用自我保护机制
  instance:
    hostname: eureka7003.com #eureka服务端的实例名称
  client:
    register-with-eureka: false #false 表示不向注册中心注册自己
     #false表示自己就是注册中心,我的职责就是维护服务实例,并不需要去检索服务
    fetch-registry: false
    service-url:
    #设置与Eureka Server交互的地址查询服务和注册服务都需要这个地址
#      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/  #(单机)
#      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/
      defaultZone: http://eureka7001.com:7001,http://eureka7002.com:7002
 
    

最重要的一点==修改映射文件:==打开C盘,找到这个路径下的hosts文件:C:\Windows\System32\drivers\etc
编辑hosts文件添加映射配置:
在这里插入图片描述

在这里插入图片描述
host文件中的Eureka
在这里插入图片描述
在这里插入图片描述
修改8001工程的application.yml文件里的defaultZone服务注册路径,具体配置如下:

server:
#指定服务器端口号8001
  port: 8001
  
mybatis:
#mybatis配置文件所在路径
  config-location: classpath:mybatis/mybatis.cfg.xml
   #所有Entity别名类所在包
  type-aliases-package: com.lyj.springcloud.entities
   #mapper映射文件所在路径
  mapper-locations:
  - classpath:mybatis/mapper/**/*.xml
  
spring:
  application:
   # 当前应用(服务)起的名字
    name: microservicecloud-dept       
  datasource:
  #当前数据源操作类型
    type: com.alibaba.druid.pool.DruidDataSource
    #mysql驱动包
    driver-class-name: com.mysql.jdbc.Driver
     #数据库名称
    url: jdbc:mysql://localhost:3306/cloudDB01
    username: mysql
    password: 15827318595
    dbcp2: 
       min-idle: 5        #数据库连接池的最小维持连接数
       initial-size: 5    #初始化连接数5个
       max-total: 5       #设置最大连接数
       max-wait-millis: 200  #s等待连接获取的最大超时时间
      

#配置Eureka
eureka:
#客户端注册进Eureka服务列表内
  client:
    service-url:
#      defaultZone: http://localhost:7001/eureka #(单机版服务器)
#        集群配置(多台服务器共同使用)
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
      
  #自定义实例的statusIP地址名字(主机名字:服务名称修改,不采用默认的名字)
  instance:
    instance-id: microservicecloud-dept8001
    prefer-ip-address: true #访问路径可以显示IP地址
    
    
#配置Eurekaweb界面访问各个服务的的详细信息的info界面
info:
  app.name: lyj-microservicecloud
  company.name: www.lyj.com
  build.artifactId: $project.artifactId$
  build.version: $project.version$
    

最后依次启动服务器7001、7002、7003工程,和服务提供者工程。
测试:
依次访问:http://eureka7001.com:7001/
http://eureka7002.com:7002/
http://eureka7003.com:7003/
并且可以在这个三个界面里按照下图:可以点击1查看该服务的我们自己自定义的信息。
点击2或者3可以跳转到7002或者7003服务器,并且都可以正常操作。
在这里插入图片描述

面试常考题

1.Eureka是什么?

Eureka是Netflix的一个子模块,也是核心模块之一,Eureka是一个基于REST的服务,用于定位服务,以实现云端中间层服务发现和故障转移。服务注册于发现对于微服务架构来说是非常重要,有了服务发现与注册,只需要使用服务的标识符,就可以访问到服务,而不需要修改服务调用的配置文件,功能类似dubbo的注册中心,比如zookeeper。

2.传统的ACID什么?&CAP是什么在这里插入图片描述

ACID:原子性(Atomicity)、一致性(Consistency)、独立性(lsolation)、持久性(Durability)
原子性:事务里的所有操作要么做,要么都不做,事务成功的条件是事务里所有操作都成功,只要有一个操作失败、整个事务失败。
一致性:数据库要一直处于一致状态,事务运行不会改变数据库原本的一致性约束
独立性:并发的事务之间不会互相影响,如果一个事务要访问的数据正在被另外一个事务修改,只要另外一个事务未提交,它所访问的数据就不受未提交事务的影响。
持久性:一旦事务提交后,它所做的修改将会永久的保存在数据库上,即使出现宕机也不会丢失。

CAP:一致性(Consistency)、可用性(Availability)、分区容错性(Partition Tolerance)
经典CAP图
在这里插入图片描述
CAP理论图:
在现在集群分布式的开发过程中,CAP三个条件最多只能同时较好的满足两个
CAP理论的核心:一个分布式系统不可能同时很好的满足一致性,可用性和分区容错性这三个需求,因此,根据CAP原理将NOSQL数据库分成了满足CA原则、满足CP原则、满足AP原则三大类:
CA-单点集群,满足一致性、可用性的系统,通常在可扩展上不太强大
CP-满足一致性,分区容错性的系统,通常性能不是很高。
AP-满足可用性、分区容错性的系统,通常可能对一致性要求低一些。
CAP的3进2
CAP理论就是说再分布式存储系统中,最多只能实现上面的两点。而由于当前的网络硬件肯定会出现延迟丢包等问题,所以分区容错性是我们必须需要实现的
所以我们只能在一致性和可用性之间进行权衡,没有NOSQL系统能同时保证这三点。
CA传统的Oracle数据库
AP大多数网站架构的选择
CPRedis、MongoDB
注意:分布式架构的时候必须做出取舍

3.Netflix在设计Eureka时遵守的就是AP原则,啥是AP原则

面试必问:
Eureka与zookeeper的区别?
答:Eureka遵守AP,zookeeper遵守CP
在这里插入图片描述

4. 作为服务注册中心,Eureka比zookeeper好在哪里?

在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

凌兮~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值