使用idea搭建springcloud
Eureka注冊中心的搭建
一).創建module
1.![1574059959112]
\1574059959112.png)
二).pom.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.springcloud</groupId>
<artifactId>test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>test</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Hoxton.RC2</spring-cloud.version>
</properties>
<dependencies>
<!-- 注冊中心jar包依賴 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</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>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
</repository>
</repositories>
</project>
三) .yml文件
#注冊中心的名字
spring:
application:
name: my-eureka
#服務端口
server:
port: 10211
#注冊中心相關配置
eureka:
server:
# 配置關閉自我保護,並按需配置Eureka Server清理無效節點的時間間隔(5000ms)。
enable-self-preservation: false
eviction-interval-timer-in-ms: 5000
client:
# 不將自己注冊到注冊中心
register-with-eureka: false #fasle:
# 因為自己是注冊中心,因此不用檢索服務信息
fetch-registry: false #true: Cannot execute request on any know server
# 注冊中心的地址
service-url:
defaultZone: http://localhost:10211/eureka/
instance:
prefer-ip-address: true
四).啟動類加入 @EnableEurekaService注解
//注冊中心
@EnableEurekaServer
@SpringBootApplication
public class TestApplication {
public static void main(String[] args) {
SpringApplication.run(TestApplication.class, args);
}
}
五).檢驗是否搭建成功
localhost:10211
構建服務,將服務注冊到注冊中心
一).構建模型:
注:構建模型時要將web組件和spring cloud discovery組件給選上,否則服務注冊不到注冊中心
二).application.yml
spring:
application:
name: client-test
#服務端口
server:
port: 10212
# 注冊中心地址
eureka:
client:
service-url:
defaultZone: http://localhost:10211/eureka/
instance:
prefer-ip-address: true
三).啟動類加入EnableEurekaClient注解
package com.own.client;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
@EnableEurekaClient
@SpringBootApplication
public class ClientApplication {
public static void main(String[] args) {
SpringApplication.run(ClientApplication.class, args);
}
}
四).開啟啟動類將服務注冊到注冊中心
根據注冊中心實現服務與服務之間的調用
參考:https://blog.csdn.net/weixin_40170892/article/details/99644429
一).搭建服務
首先,我們搭建兩個服務。server-provider(服務調用者),server-caller(服務調用者)
搭建服務的過程與上文構建服務,將服務注冊注冊到注冊中心的做法一致。
二).server-caller(服務調用者)需要添加如下配置
1).在pom.xml中引入fegin的jar包依賴
<!-- feign微服務調用 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ope nfeign</artifactId>
</dependency>
pom.xml如下
<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.own</groupId>
<artifactId>server-caller</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>server-caller</name>
<description>服務調用者</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Hoxton.RC2</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-client</artifactId>
</dependency>
<!-- feign微服務調用 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</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>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
</repository>
</repositories>
</project>
2).啟動類加入注解@EnableFeignClient,@EnableEurekaClient
@EnableFeignClients //允許服務調用
@EnableEurekaClient //允許注冊到注冊中心
@SpringBootApplication
public class ServerCallerApplication {
public static void main(String[] args) {
SpringApplication.run(ServerCallerApplication.class, args);
}
}
三).在server-provider(服務提供者)中定義被調用的方法
在controller下定義一個sayHello類,該類中有一個sayHello方法,返回一個hello
/**
* @ Author:chenxuebing
* @ Date:2019/11/25 17:30
* @ Description:服務提供者提供打招呼的服務
*/
@Controller
public class SayHello {
@RequestMapping("/hello")
@ResponseBody
public String sayHello(){
return "hello";
}
}
四).在server-caller()(服務調用者)中調用server-provider(服務提供者)的sayHello方法
實現:
1).首先,需要提供一個接口,接口中的方法與server-provider(服務提供者)的方法 一樣,但只聲明不實現。
2).其次,在接口上加入注解@FeignClient("引用的服務名稱"),在這里我給我的引用服務起名為server-provider,那么就是@FeignClient(value = "server-provider")
服務調用者接口聲明的特點是:
1).方法聲明和server-provider的方法聲明相同
2)請求方式也相同,例如:post、get、put...
3).對應的請求映射路徑也相同
4).加入@FeignClient(value = "被調用的服務"),聲明被調用的服務
/**
* @ Author:chenxuebing
* @ Date:2019/11/26 9:10
* @ Description:調用service-provider的SayHello類的方法
*/
/**
* 調用者的接口方法是被調用者方法的聲明,映射路徑與被調用者方法的映射路徑相同
*/
@FeignClient(value = "server-provider") //調用的服務名稱
public interface SayHelloCaller {
@RequestMapping("/hello")
public String sayHello();
}
好啦,這下我們就可以寫一個controler來測試一下我們是否能成功調用。
controler中類的定義如下:
定義一個Person的控制類,該類可以調用server-provider(服務調用者)的sayHello方法,具有向別說hello的功能。
/**
* @ Author:chenxuebing
* @ Date:2019/11/26 9:30
* @ Description:打招呼的一個對象
*/
@Controller
public class Person {
@Autowired
private SayHelloCaller caller;
@RequestMapping("/sayHello")
@ResponseBody
public String sayHello(){
return caller.sayHello();
}
}
注意在使用服務間調用的一個坑!!!
堆棧溢出錯誤:
為什么會這樣呢? 唔、、、我好艱難啊! 掉眼淚。。哇哇 哇
因為我在控制器里邊聲明的方法和server-provider中的方法是同名的,都是sayHello(),然后我就天真的直接寫了return sayHello();這當然不行啦!!!這相當於遞歸操作呀,調用的是自己的sayHello(), sayHello()方法跑不出去,當然會報stackOverflowError(堆棧溢出錯誤)。
正確的做法是:---》
你應該使用@Authowire將接口sayHelloCaller注入,調用它的sayHello()呀!,我真是蠢到爆了! bang!
五).測試是否能成功調用
好啦,開啟服務調用咱們看運行結果:
我在項目配置的server-provider的端口號是:10214,server-caller配置的端口號是10213,由下圖可見,我們在server-caller服務中成功的訪問了server-provider提供的sayHello服務。
使用Zuul網關實現服務的分發
一).使用idea構建Zull模塊
web、spring cloud Discovery zull模塊都選上
創建好模塊如下:
二).配置網關服務
1).配置application.yml文件
設置路由映射路徑:
zuul:
routes:
api-a: #用來區分不同服務的一個名字,可以隨便取
path: /client/** #zuul網關訪問服務的一個路徑
serviceId: client-test #所要訪問的服務對應的注冊中心的名稱
spring:
application:
name: gateway
server:
port: 10215
zuul:
routes:
# 面向服務的路由
api-a:
path: /client/**
serviceId: client-test #client-test 對應的是注冊中心的服務的名稱
#服務分發的方式是這樣的,我們通過localhost:10215/client訪問,實際是將地址映射到了client-test這個服務的地址上
# 傳統的路由
api-b-url:
path: /caller/**
#由傳統的路由模式,我們可以知道用戶訪問的路由路徑為localhost:10215/caller,將服務映射到了http://localhost:10213
url: http://localhost:10213/
eureka:
client:
service-url:
defaultZone: http://localhost:10211/eureka/
2).在啟動類上加上注解@EnabelZullProxy
三).由zuul來控制服務的訪問
測試,通過gateway(網關服務)來訪問,上文的client(測試將服務注冊到注冊中心),server-caller(服務調用者)這兩個服務。
1).client服務中定義一個controller類,類名為ClientServer,類中定義一個sayHello()方法
/**
* @ Author:chenxuebing
* @ Date:2019/11/26 11:53
* @ Description:client端的服務
*/
@Controller
public class ClientServer {
@RequestMapping("/sayhello")
@ResponseBody
public String sayHello(){
return "我是來自client服務端,你好呀!";
}
}
2).server-caller服務也定義controller類,類名為CallerServer,類中也定義衣蛾sayHello()方法
/**
* @ Author:chenxuebing
* @ Date:2019/11/26 13:35
* @ Description:調用者服務端
*/
@Controller
public class CallerServer {
@RequestMapping("/sayhello")
@ResponseBody
public String sayHello(){
return "我是來自caller的服務端,你好呀!";
}
}
四).測試由zull來分發服務
三個服務:
gateway(網關服務): 端口號10215
client(測試注冊中心服務): 端口號10216
server-caller(服務調用):端口號10213
由gateway分發對client、 server-caller服務的訪問
測試:訪問client的sayHello()方法
通過網關地址locallhost:10215/client 進行訪問, client將地址映射到serviceId上對應的client服務對應的地址。
測試:訪問server-caller的sayHello()方法
通過localhost:10215/caller進行訪問,caller將地址映射到url對應的server-caller服務對應的服務地址。