使用springCloud的Eureka+Feign实现两个微服务之间的调用
一.简介
对于微服务,本人自己最近也是在摸索之中,下面这篇算是sprinCloud入门级,通过这个案例,至少会知道什么是微服务。
二.需求
在实现之前要先清楚想干嘛实现什么东西,带着思路去实现,这样才能知道为什么要这么做。假设现在有个基于微服务设计的宠物管理系统,系统被拆分成多个服务,其中有两个服务为用户服务、宠物服务。现在的需求是用户服务想要查看宠物服务的信息,比如用户A想要查看有哪些种类的宠物狗。
三.设计思想
先创建一个Eureka注册中心服务端用与管理其他Eureka注册中心客户端的信息,再创建两个Eureka客户端,一个是用户服务客户端(用户微服务)另一个是宠物服务客户端(宠物微服务),此时用户服务查看宠物服务,即用户服务为请求方,宠物服务是响应方,springCloud中称用户服务为消费方(consumer),宠物服务属于供应方(provider),这两个微服务是使用springCloud的Feign组件实现通信的(这里暂不谈这种通信方式的好坏,想了解更多通信方式可以搜索webService)。
四.实现
4-1.创建Eureka服务端
1.打开Intellij IDEA新建一个项目,File -->New -->Project。
2.选择Spring Initializr,然后点击Next按钮。耐心等待,可能会很慢,如果老是失败就把网址换成阿里云提供的网址,更改Default处的为下面的Custom,网址输入https://start.aliyun.com/。
3.修改项目信息,这是弹出的界面,修改其中的信息
我修改了这四个地方,按要求修改就行,修改后点击Next.
4.勾选需要的组件
2处Eurake Server表示这是个注册中心服务端,版本此处我选择的是最高版,这个要特别注意,之后的版本尽量选择和这个版本统一,而且推荐不要选择最新版。
点击Finish
等待依赖的下载完成,下面是pom文件,如果出现报错,就将版本号声明下,否则就不用做修改。
5.增加注解
找到启动类,增加注解@EnableEurekaServer
6.编辑配置文件,推荐将properties改为yml格式
输入以下信息,注意格式,完成后点击启动按钮
可以直接复制下面这段信息的,也可以照着截图自己改,因为我后面更新了下这个配置信息(之前图片太模糊了),所以截图和下面这段信息有所误差。
server:
port: 8000
eureka:
client:
service-url:
#这是注册中心服务端的地址,告诉别的服务我在这个位置,之后将别的服务信息注册到这个位置来
defaultZone: http://localhost:8000/eureka/
#表示是否从Eureka Server获取注册的服务信息,这就是个服务端,没必要自己获取自己
fetch-registry: false
#表示是否将当前服务注册到Eureka Server 一样的道理没必要自己保管自己的信息
register-with-eureka: false
打开浏览器,输入 localhost:8000,注意不是输入配置文件中的localhost:8000/eureka/
4-2.创建宠物微服务客户端
1.创建步骤和上面类似
2.修改信息
3.勾选组件,注意要选择Web组件或者其它能够持久运行的。不然会注册失败,我试过只勾选eureka client组件项目启动不起来的。
点击Finish
4.打开启动类,添加注解@EnableEurekaClient。
这里说明下EnableEurekaClient和@EnableDisCoveryClient都是可以的,springCloud中的discovery service有多种实现(Eureka、Zookeeper等),@EnableDiscoveryClient基于spring-cloud-commons,@EnableEurekaClient基于spring-cloud-netflix。
就是如果选用的注册中心是Eureka,那么就推荐@EnableEurekaClient,如果是其他的注册中心,那么推荐使用@EnableDiscoveryClient。
5.修改配置文件,添加如下信息。
server:
port: 1002
#指定项目对外的名字,为方便记忆与项目名一致就行了
spring:
application:
name: eureka-pet-client
#将此服务注册到注册中心的服务端中,此处的地址为Eureka服务端对外公开的地址
eureka:
client:
service-url:
defaultZone: http://localhost:8000/eureka/
启动项目(下面是旧图很模糊,信息也没来的即改不用管)
刷新Eureka服务端网页,可以看到已经将服务注册进去了。
6.上面的步骤成功了,就可编写宠物微服务的功能代码了。
把项目结构先贴出来
先建个实体类
package com.springcloudbase.eurekapetclient.entity;
public class Dog {
private String name;
private Integer age;
/**
* 种类
*/
private String type;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
建个DogService接口
package com.springcloudbase.eurekapetclient.service;
import com.springcloudbase.eurekapetclient.entity.Dog;
import java.util.List;
public interface DogService {
/**
* 查询所有狗的信息
* @return
*/
List<Dog> queryDogs();
}
创建实现类实现查询方法
package com.springcloudbase.eurekapetclient.service.impl;
import com.springcloudbase.eurekapetclient.entity.Dog;
import com.springcloudbase.eurekapetclient.service.DogService;
import java.util.ArrayList;
import java.util.List;
@Service
public class DogServiceImpl implements DogService {
@Override
public List<Dog> queryDogs() {
//模拟数据库中的数据
Dog dog01 = new Dog();
dog01.setName("小黑");
dog01.setAge(1);
dog01.setType("中华田园犬");
Dog dog02 = new Dog();
dog02.setName("小白");
dog02.setAge(2);
dog02.setType("哈士奇");
List<Dog> dogList = new ArrayList<>();
dogList.add(dog01);
dogList.add(dog02);
return dogList;
}
}
新建DogController类
package com.springcloudbase.eurekapetclient.controller;
import com.springcloudbase.eurekapetclient.entity.Dog;
import com.springcloudbase.eurekapetclient.service.DogService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
public class DogController {
@Autowired
private DogService dogService;
/**
* 若遵循RestFul风格,查询应该用Get请求才对,但是Feign不支持Get请求传递POJO对象,
* 所以此处我采用了Post的请求方式
* @param dog
* @return
*/
@PostMapping("queryDogs")
public List<Dog> queryDogs(Dog dog){
return dogService.queryDogs();
}
}
到pom文件中加入Feign的依赖,并刷新Maven。
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
到启动类中加入@EnableFeignClients
注解
项目结构如下,重启项目,项目结构如下
4-3.创建用户微服务客户端
创建步骤和宠物微服务端几乎一样,只贴图了。
启动类中添加@EnableEurekaClient
注解
配置文件信息如下
server:
port: 1001
#对外的项目名,为方便记忆就和项目名一致
spring:
application:
name: eureka-user-client
#将此服务注册到注册中心,地址填写注册中心服务端中的地址
eureka:
client:
service-url:
defaultZone: http://localhost:8000/eureka/
启动项目
刷新服务端的网页,用户微服务客户端信息已经被注册到服务端了。
接下来编写功能代码 实现调用用宠物微服务端的方法
先到pom文件中引入Feign依赖,再到启动类上加入@EnableFeignClients,步骤同前面一模一样。
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
到启动类中加入@EnableFeignClients
注解
先贴出项目结构
创建Dog实体类,同上,直接复制前面创建过的Dog实体类然后粘贴,修改下包名。
创建一个FeignClient接口用于调用宠物微服务中的方法。
package com.springcloudbase.eurekauserclient.client;
import com.springcloudbase.eurekauserclient.entity.Dog;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import java.util.List;
/**
* eureka-pet-client 为供应方对外公开的项目名,即yml中配置的application-name
*/
@FeignClient("eureka-pet-client")
public interface DogClient {
/**
* queryDogs为 供应方的Controller地址
* @return
*/
@PostMapping("queryDogs")
public List<Dog> queryDogs(Dog dog);
}
创建Controller
package com.springcloudbase.eurekauserclient.controller;
import com.springcloudbase.eurekauserclient.client.DogClient;
import com.springcloudbase.eurekauserclient.entity.Dog;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
public class UserController {
@Autowired
private DogClient dogClient;
@GetMapping("userQueryDogs")
public List<Dog> userQueryDogs(Dog dog){
return dogClient.queryDogs(dog);
}
}
重启项目,刷新Eureka服务端网页,可以看到两条注册信息了,现在这两个服务是部署在同一台机器上的,等学会了docker后就可以模拟出部署在不同机器上了,还可以为Eureka服务端做集群以提高可用性。
五.测试
使用postman或者直接在浏览器上输入 localhost:1001/userQueryDogs
,可以看到用户服务成功调用了宠物服务中的查询方法。这个网址是用户服务的网址,但是却调用了宠物服务中的方法。
六.总结
其实这些框架让我们建项目越来越简单。在敲代码搭环境之前,首先搞清楚自己要干嘛,为什么这么做,如果不知道自己为什么要做这些步骤,即使照着别人的敲,效率是非常低的,如果知道了思想清楚步骤,照着做一两遍基本就可以记住了。POM文件报错,很可能是网络环境不好(并不是真的网速慢)导致jar包其实并没有下载下来。