一、Eureka实现服务发现和注册
1.新建maven空的父项目(SpringCloud)
由于使用的模块型开发,故创建一个父工程,用于储存子模块共用的依赖,下面是文件夹树
2)pom文件依赖如下
<!-- lookup parent from repository -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.10.RELEASE</version>
<relativePath/>
</parent>
<!-- 子模块依赖不用显示表明依赖版本,统一沿用父项目的依赖版本 -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Edgware.SR2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
3)新建子模块注册中心maven工程(Eureka'Server1),子模块依赖如下
<dependencies>
<!-- Eureka服务端开始 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
</dependency>
<!-- Eureka服务端结束 -->
</dependencies>
4)编写注册中心配置文件,application.yml,不设置defaultZone时,默认是http://localhost:8761/eureka
#注册中心端口
server:
port: 8083
eureka:
client:
#由于注册中心的职责就是维护服务实例,它并不需要去检索服务,所以也设置为false
fetch-registry: false
#由于该应用为注册中心,所以设置为false,代表不向注册中心注册自己
register-with-eureka: false
service-url:
defaultZone: http://localhost:8083/eureka
#是否优先从文件系统加载template
spring:
freemarker:
prefer-file-system-access: false
5)编写启动类,一个简单java类就行,如果不配置去除数据库源,启动时会找不到数据库源而报异常
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
/**
* 去除自动注入数据库源
* exclude = {DataSourceAutoConfiguration.class,HibernateJpaAutoConfiguration.class}
* Eureka服务端声明注解标签EnableEurekaServer
*/
@EnableEurekaServer
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class,HibernateJpaAutoConfiguration.class})
public class EurekaServer {
public static void main(String[] args) {
SpringApplication.run(EurekaServer.class);
}
}
6)启动和访问注册中心界面,http://localhost:8083/,看到如下界面证明注册中心启动成功。
2.服务发现和注册
1)编写子模块maven工程(FeignClient1),导入依赖,pom文件内容如下
<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</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- euraka实现服务发现和注册的依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<!-- Feign依赖,为使用Feign进行服务调用作准备,服务注册和发现时可不导入 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
2)编写application.yml配置文件
server:
port: 8082
spring:
application:
name: FeignConsumer #在注册中心注册服务时使用的名字
freemarker:
prefer-file-system-access: false
eureka:
client:
service-url:
#必须配上和注册中心一样的地址,否则注册不成功
defaultZone: http://localhost:8083/eureka
#Feign在新版本中默认是没有开启Hystrix的功能
#必须开启Hystrix才能回调成功(被调用服务异常时回调)
feign:
hystrix:
enabled: true
3)编写服务注册和发现启动类
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.feign.EnableFeignClients;
/**
* EnableEurekaClient配置被注册中心发现
* EnableFeignClients配置为进行服务调用
*/
@EnableFeignClients
@EnableEurekaClient
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class,args);
}
}
4)启动服务,进入注册中心页面再次查看,可查看到该服务,默认是使用主机名进行注册。
二、Feign实现服务调用和异常回调
1.编写服务提供方
1)编写子模块maven工程(FeignClient2),pom依赖如下,作为服务提供方时可不导入feign依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
2)编写配置文件application.yml
server:
port: 8084
spring:
application:
name: FeignProvider #注册在注册中心的服务名字,需提供给消费方使用
freemarker:
prefer-file-system-access: false
eureka:
client:
service-url:
defaultZone: http://localhost:8083/eureka
3)编写提供给消费方使用的服务,controller类
import org.apache.log4j.Logger;
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.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
* 提供给消费方的服务
*/
@RestController
public class FeignProController {
private Logger log = Logger.getLogger(FeignProController.class);
@Autowired
public DiscoveryClient discoveryClient;
@RequestMapping("/getInfo")
public String hello(@RequestParam("name") String name){
ServiceInstance serviceInstance = discoveryClient.getLocalServiceInstance();
String host = serviceInstance.getHost();
int port = serviceInstance.getPort();
String info = "hello name="+ name + ",host=" + host + ",port=" + port;
log.info(info);
return info;
}
}
4)编写服务启动类,被调用的服务也可以在注册中心注册
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
@EnableEurekaClient
@SpringBootApplication
public class FeignProApplication {
public static void main(String[] args) {
SpringApplication.run(FeignProApplication.class);
}
}
5)启动服务提供方
2.编写服务消费方
由于在服务注册和发现时已经建立了子模块(FeignClient1),这里继续往下进行。
1)编写FeignServiceClient接口,必须为接口,类是不可以的,代码如下
import com.dc.wangrt.service.impl.FeignServiceClientFallback;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
/**
* FeignProvider为被调用的服务在注册中心上注册的名字
* fallback配置是当被调用服务挂掉之后所产生的回调,这里是回调到另一个类
*/
@FeignClient(value = "FeignProvider",fallback = FeignServiceClientFallback.class)
public interface FeignServiceClient {
//该方法必须和被调用服务的定义一致
@RequestMapping("/getInfo")
public String hello(@RequestParam("name") String name);
}
2)编写1)中接口实现类,即回调类(FeignServiceClientFallback),回调时必须在application.yml中显示设置feign.hystrix.enabled=true,因为新版本中Hystris默认是不开启的
import com.dc.wangrt.service.FeignServiceClient;
import org.springframework.stereotype.Component;
/**
* 回调内容
*/
@Component
public class FeignServiceClientFallback implements FeignServiceClient {
@Override
public String hello(String name) {
System.out.println("回调成功!!!");
return "sorry " + name + ", feign client error";
}
}
3)编写调用服务类(FeignController)
import com.dc.wangrt.service.FeignServiceClient;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class FeignController {
private Logger log = Logger.getLogger(FeignController.class);
@Autowired
private FeignServiceClient feignServiceClient;
@GetMapping("/getInfo")
public String hello(@RequestParam("name") String name){
String info = feignServiceClient.hello(name);
log.info(info);
return info;
}
}
4)服务启动,访问http://localhost:8082/getInfo?name=wangrt,可以看到服务被正常调用
5)把被调用服务关闭之后,再次调用,可以看到进行回调了,证明异常时服务也可以正常回调,不会抛出异常
三、总结
至此,使用Eureka实现服务发现、注册和Feign实现服务的调用和异常时回调就完成了,欢迎大家在评论区多多点评,一起学习,共同进步。