Spring Cloud实践之服务注册与发现Eureka

时间:2023-03-09 05:42:34
Spring Cloud实践之服务注册与发现Eureka

一、简述:

服务提供者producer与服务消费者consumer都注册到eureka server,然后服务consumer在其应用内直接调用producer的服务名来调用服务,而不是像之前一样调用producer的IP:port的url来调用他的rest API。(实际的过程是,consumer向eureka获取了producer的地址,然后再调用producer)

二、配置使用

1、eureka server:

@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
private static final Logger LOGGER = LoggerFactory.getLogger(EurekaServerApplication.class);
public static void main(String[] args) {
LOGGER.info("服务注册与发现服务器启动...");
SpringApplication.run(EurekaServerApplication.class, args);
}
}

application.properties

# server
server.port=8761
# spring
spring.application.name=eureka-server
# eureka
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
eureka.client.serviceUrl.defaultZone=http://localhost:${server.port}/eureka/
#security
security.basic.enabled=true
security.user.name=liny
security.user.password=123456

build.gradle

/*
* This build file was generated by the Gradle 'init' task.
*
* This generated file contains a sample Java Library project to get you started.
* For more details take a look at the Java Libraries chapter in the Gradle
* user guide available at https://docs.gradle.org/4.3/userguide/java_library_plugin.html
*/
buildscript {
ext {
springBootVersion = '1.4.2.RELEASE'
}
repositories {
mavenCentral()
jcenter()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
// Apply the java-library plugin to add support for Java Library
apply plugin: 'java-library'
apply plugin: 'java'
apply plugin: 'org.springframework.boot' version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8
// In this section you declare where to find the dependencies of your project
repositories {
// Use jcenter for resolving your dependencies.
// You can declare any Maven/Ivy/file repository here.
jcenter()
mavenCentral()
maven { url "http://dl.bintray.com/oembedler/maven" }
maven { url "https://repo.spring.io/libs-release" }
maven { url "http://10.100.122.249:8881/nexus/content/groups/public/" }
} dependencyManagement {
imports {
//mavenBom 'org.springframework.cloud:spring-cloud-netflix:1.2.0.M1'
mavenBom 'org.springframework.cloud:spring-cloud-dependencies:Camden.SR2'
}
} dependencies {
// Use JUnit test framework
testImplementation 'junit:junit:4.12'
compile("org.springframework.cloud:spring-cloud-starter-parent:Camden.SR2")
//开启安全验证
compile("org.springframework.boot:spring-boot-starter-security")
compile("org.springframework.boot:spring-boot-starter-web")
compile("org.springframework.boot:spring-boot-starter-actuator")
compile("org.springframework.boot:spring-boot-starter-test")
compile("org.springframework.cloud:spring-cloud-starter-eureka-server")
}

  2、服务提供者

主程序上加@EnableEurekaClient注解,表示把自己注册到eureka

application.properties里添加如下配置:

# eureka
eureka.client.serviceUrl.defaultZone=http://liny:123456@localhost:8761/eureka/
#spring
spring.application.name=core

butild.gradle

与eureka server不同的是添加的依赖是org.springframework.cloud:spring-cloud-starter-eureka,而eureka server是org.springframework.cloud:spring-cloud-starter-eureka-server

buildscript {
ext {
springBootVersion = '1.4.2.RELEASE'
}
repositories {
mavenCentral()
jcenter()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
} apply plugin: 'java'
apply plugin: 'org.springframework.boot' version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8 repositories {
mavenCentral()
maven { url "http://dl.bintray.com/oembedler/maven" }
maven { url "https://repo.spring.io/libs-release" }
maven { url "http://10.100.122.249:8881/nexus/content/groups/public/" }
} dependencyManagement {
imports {
mavenBom 'org.springframework.cloud:spring-cloud-dependencies:Camden.SR2'
}
} dependencies {
compile("org.springframework.cloud:spring-cloud-starter-config")
compile("org.springframework.cloud:spring-cloud-starter-eureka")
compile group: 'org.springframework.boot',name:'spring-boot-starter-web',version:'1.4.4.RELEASE'
compile group: 'org.springframework.boot',name:'spring-boot-starter-test',version:'1.4.4.RELEASE'
compile group: 'org.springframework.boot', name: 'spring-boot-starter-data-jpa', version: '1.4.4.RELEASE'
compile group: 'mysql', name: 'mysql-connector-java', version:'5.1.18'
compile group: 'org.apache.tomcat', name: 'tomcat-jdbc', version: '8.0.32'
compile group: 'cglib', name: 'cglib-nodep', version:'2.2'
compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.4'
compile group: 'commons-io', name: 'commons-io', version: '2.4'
compile group: 'com.alibaba', name: 'fastjson', version: '1.2.23'
compile group: 'commons-codec', name: 'commons-codec', version: '1.10'
compile group: 'org.apache.httpcomponents', name: 'fluent-hc', version:'4.3.1'
compile group: 'io.springfox', name: 'springfox-swagger-ui', version: '2.6.1'
compile group: 'io.springfox', name: 'springfox-swagger2', version: '2.6.1'
compile'org.projectlombok:lombok:1.16.18'
compile group: 'com.qiniu', name: 'qiniu-java-sdk', version: '7.2.1'
testCompile group: 'junit', name: 'junit', version: '4.11'
} bootRepackage {
mainClass = 'com.hzydbs.MainApplication'
}

服务消费者:

主程序

@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class MainApplication {
public static void main(String[] args) {
SpringApplication.run(MainApplication.class, args);
}
}

同样的,服务消费者也需要注册到eureka,同时@EnableFeignClients意思是将使用Feign作为http rest API接口调用工具。feign允许用类似rpc的方式调用远程接口在本地的映射,像调用本地方法那样调用远程接口。但这里其本质上是http协议。

application.properties   只需要配置eureka的地址,而不再需要配置服务提供者的地址了

# eureka
eureka.client.serviceUrl.defaultZone=http://liny:123456@localhost:8761/eureka/

现在假设服务消费者gateway需要调用服务提供者core上这样一个REST接口方法:

@RequestMapping(value = "getOne", method = RequestMethod.GET)
public ItemResponse getOne(@RequestParam(required = true) long itemId)

我们只需在服务消费者心中一个interface

@FeignClient(name= "core")
public interface CoreRemote {
@RequestMapping(value = "/item/getOne", method = RequestMethod.GET)
public ItemResponse getOne(@RequestParam(value = "itemId") long itemId);
}
@FeignClient(name= "core")意思是映射服务名为core的应用的方法,getOne与远程core上的同名方法保持入参和返回一致。

然后在消费者的程序中就可以像调用本地方法一样调用远程的方法了

@Autowired
private CoreRemote coreRemote;
....
ItemResponse itemResponse = coreRemote.getOne(itemId);

消费者这里之前遇到了一个问题:feign/Feign$Builder
Caused by: java.lang.NoClassDefFoundError: feign/Feign$Builder

网上了解了一下之后大致是spring boot与spring cloud版本之间兼容性的问题

所以这里消费者的build.gradle文件略微有些调整:

buildscript {
ext {
springBootVersion = '1.4.2.RELEASE'
}
repositories {
mavenCentral()
jcenter()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
} apply plugin: 'java'
apply plugin: 'org.springframework.boot' version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8 repositories {
mavenCentral()
maven { url "http://dl.bintray.com/oembedler/maven" }
maven { url "https://repo.spring.io/libs-release" }
} allprojects {
apply plugin: 'org.springframework.boot'
repositories {
mavenCentral()
maven { url "http://dl.bintray.com/oembedler/maven" }
maven { url "https://repo.spring.io/libs-milestone/" }
maven { url "https://repo.spring.io/libs-release" }
jcenter()
}
dependencyManagement {
imports {
mavenBom 'org.springframework.cloud:spring-cloud-dependencies:Camden.SR2'
}
}
} dependencies { compile("org.springframework.cloud:spring-cloud-starter-eureka")
compile("org.springframework.cloud:spring-cloud-starter-feign") }