Spring Cloud注册中心以及Fegin服务调服务

前言

最近项目改造,采用微服务架构,学到了如何使用Spring Cloud的注册中心以及Feign服务调用服务机制

关于介绍等等的就不说明了,网上资料很多,说的也很清楚
推荐文章服务发现和注册和Eureka

一共需要四个项目,一个是用来创建注册中心的,收发机制,服务消费者和服务注册者向服务发现组件注册,服务消费者要调用的时候会从服务发现组件中进行查询;第二个是服务客户端,第三个是提供服务的,第四个是用来测试的

1. 创建注册中心

  • 创建Spring Boot项目,在pom文件中引入eureka依赖包
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.0.3.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<java.version>1.8</java.version>
		<spring-cloud.version>Finchley.RELEASE</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>

	</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>
  • 配置文件写入eureka需要的依赖
spring.application.name=eureka-server

#服务注册中心端口号
server.port=1111

#服务注册中心实例的主机名,也就是自己的IP地址,这里是我虚拟机服务器地址,因为要部署
eureka.instance.hostname=192.168.85.129

#是否向服务注册中心注册自己
eureka.client.register-with-eureka=false

#是否检索服务
eureka.client.fetch-registry=false

#服务注册中心的配置内容,指定服务注册中心的位置
eureka.client.serviceUrl.defaultZone=http://${eureka.instance.hostname}:${server.port}/eureka/
  • 在启动类上加上注册中心注解
@EnableEurekaServer
@SpringBootApplication
public class Application {

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

启动项目,访问地址:自己的IP地址:端口号,就能看到一个注册中心的界面

2. 创建服务提供者

  • 创建Spring Boot项目,在pom文件中引入依赖
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.9.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <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.cloud</groupId>
            <artifactId>spring-cloud-starter-feign</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
        </dependency>
    </dependencies>
    <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>
  • 在配置文件中加入所需配置
server.port=8100

# feign配置
spring.application.name=app-service
#注册中心地址
eureka.client.service-url.defaultZone = http://192.168.85.129:1111/eureka/
#注册时使用ip而不是主机名

#一般其他模块调用服务都是通过hostname来访问的,本机IP地址
eureka.instance.hostname=192.168.1.104
#指定此实例注册到eureka的ip
eureka.instance.ip-address=${eureka.instance.hostname:${spring.cloud.client.ipAddress}}
#优先使用eureka.instance.ip-address
eureka.instance.instance-id=${eureka.instance.ip-address:${spring.cloud.client.ipAddress}}:${spring.application.name}:${server.port}
#请求处理的超时时间
ribbon.ReadTimeout= 30000
#请求连接的超时时间
ribbon.ConnectTimeout= 30000
  • 在启动类上加上注解
@EnableDiscoveryClient
@SpringBootApplication
public class Application {

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

启动项目,去注册中心上查看一下自己是否注册成功,成功会看到一个表单

ApplicationAMIsAvailabilityZones
APP-SERVICEn/a (1)(1)UP (1) - 192.168.85.129:app-service:8100
  • 随便写一个Controller
@RestController
@RequestMapping("/app")
public class TextController {
    @GetMapping("/hello")
    public TextDTO hello(){
        TextDTO textDTO = new TextDTO();
        textDTO.setName("测试数据");
        textDTO.setSex("测试数据");
        return textDTO;
    }
}

3. 创建Feign服务客户端

  • 创建Spring Boot项目,引入POM文件依赖
<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>1.5.9.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<java.version>1.8</java.version>
		<spring-cloud.version>Edgware.RELEASE</spring-cloud.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-feign</artifactId>
		</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>
  • 创建一个数据传输DTO
public class TextDTO implements Serializable{

    private String name;
    private String sex;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }
}
  • 创建一个Service接口
@FeignClient(name = "app-service", path = "/app")
public interface TextService {
    @GetMapping("/hello")
    TextDTO hello();
}

细心的会发现,这个Service接口上的注解中name属性,对应的其实是刚才提供者配置文件中的spring.application.namepath属性对应的是提供者Controller类上的@RequestMapping("/app"),而接口的方法就是提供者的方法,调用服务的时候,Feign就是通过这两个去注册中心查询的,找到name叫app-service的服务,找到这个服务下的一个方法,再由注册中心把这个找到的数据通过数据传输DTO返回给消费者

注意: Get或者Post请求一定要两边同步,方法也是,另外最重要的一点,也是一个坑,这里演示的是无参的方法,调用有参的方法时,一定要在参数上加上@RequestParam注解,并且明确name属性,至于required随意,不然会报错,正确示例:

@FeignClient(name = "app-service", path = "/app")
public interface TextService {
    @GetMapping("/hello")
    TextDTO hello(@RequestParam(name = "id", required = true) String id);
}

4. 测试

  • 创建一个Spring Boot项目,pom文件引入依赖
<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>1.5.9.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<java.version>1.8</java.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>
			<groupId>com.eureka</groupId>
			<artifactId>eureka-client</artifactId>
			<version>0.0.1-SNAPSHOT</version>
		</dependency>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-eureka</artifactId>
		</dependency>
	</dependencies>
	<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>
  • 配置文件加入所需的配置
server.port=8200

# feign配置
spring.application.name=app-demo
#注册中心地址
eureka.client.service-url.defaultZone = http://192.168.85.129:1111/eureka/
#注册时使用ip而不是主机名

#一般其他模块调用服务都是通过hostname来访问的,本机IP地址
eureka.instance.hostname=192.168.1.104
#指定此实例注册到eureka的ip
eureka.instance.ip-address=${eureka.instance.hostname:${spring.cloud.client.ipAddress}}
#优先使用eureka.instance.ip-address
eureka.instance.instance-id=${eureka.instance.ip-address:${spring.cloud.client.ipAddress}}:${spring.application.name}:${server.port}
#请求处理的超时时间
ribbon.ReadTimeout= 30000
#请求连接的超时时间
ribbon.ConnectTimeout= 30000
  • 在启动类上加上注解
@EnableDiscoveryClient
//basePackages 一定要加,不然会启动报错,加的这个是Feign服务客户端包名
@EnableFeignClients(basePackages = {"com.eureka"})
@SpringBootApplication
public class Application {

	public static void main(String[] args) {
		SpringApplication.run(Application.class, args);
	}
}
  • 测试调用,可以在Service实现类里,也可以在Controller里做测试
@RestController
@RequestMapping
public class DemoController {
    @Resource
    private TextService textService;
    @GetMapping("/")
    public TextDTO hello(){
        return textService.hello();
    }
}

启动项目,先查看有没有在注册中心中找到自己,注册成功才行,然后调用接口,之前要是配置没出错就能看到,Feign已经成功帮我们服务调服务拿到了数据

{
  "name": "测试数据",
  "sex": "测试数据"
}

这样的好处是,我不需要知道这个服务的表结构,也不需要他们的数据库类型,需要什么接口,让提供者开一个,然后消费者调用就好,当所有服务都在注册中心的时候,一个大的项目跑起来,不会说一个地方挂了全部都挂了,一个服务挂了,项目正常跑,只是某些功能没有了,这个时候等服务修好了再启动,就能正常使用

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值