服务注册与发现
概述
在这里,我们需要用的组件是 Spring Cloud Netflix 的 Eureka,Eureka 是一个服务注册和发现模块
创建服务注册中心
新建目录
新建pom
4.0.0
com.funtl
hello-spring-cloud-dependencies
1.0.0-SNAPSHOT
../hello-spring-cloud-dependencies/pom.xml
hello-spring-cloud-eureka
jar
hello-spring-cloud-eureka
http://www.suntong.com
2019-Now
org.springframework.boot
spring-boot-starter-test
test
org.springframework.cloud
spring-cloud-starter-netflix-eureka-server
org.springframework.boot
spring-boot-maven-plugin
com.suntong.hello.spring.cloud.eureka.EurekaApplication
手动让maven管理此项目
创建源码目录
创建资源文件目录
新建配置文件
新建入口类
配置sdk
EurekaApplication.java
package com.suntong.hello.spring.cloud.eureka;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@SpringBootApplication
@EnableEurekaServer //开启Eureka服务端
public class EurekaApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaApplication.class, args);
}
}
application.yml
spring:
application:
name: hello-spring-cloud-eureka
server:
port: 8761
eureka:
instance:
hostname: localhost
client:
registerWithEureka: false #不加这两句代表是客户端
fetchRegistry: false
serviceUrl:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
pom.xml
4.0.0
com.funtl
hello-spring-cloud-dependencies
1.0.0-SNAPSHOT
../hello-spring-cloud-dependencies/pom.xml
hello-spring-cloud-eureka
jar
hello-spring-cloud-eureka
http://www.suntong.com
2019-Now
org.springframework.boot
spring-boot-starter-test
test
org.springframework.cloud
spring-cloud-starter-netflix-eureka-server
org.springframework.boot
spring-boot-maven-plugin
com.suntong.hello.spring.cloud.eureka.EurekaApplication
运行入口类
Eureka Server 是有界面的,启动工程,打开浏览器访问:
http://localhost:8761
创建服务提供者
概述
当 Client 向 Server 注册时,它会提供一些元数据,例如主机和端口,URL,主页等。Eureka Server 从每个 Client 实例接收心跳消息。 如果心跳超时,则通常将该实例从注册 Server 中删除
构建项目
项目结构同之前一样
pom.xml
4.0.0
com.suntong
hello-spring-cloud-dependencies
1.0.0-SNAPSHOT
../hello-spring-cloud-dependencies/pom.xml
hello-spring-cloud-service-admin
jar
hello-spring-cloud-service-admin
http://www.suntong.com
2018-Now
org.springframework.boot
spring-boot-starter-test
test
org.springframework.cloud
spring-cloud-starter-netflix-eureka-server
org.springframework.boot
spring-boot-maven-plugin
com.funtl.hello.spring.cloud.service.admin.ServiceAdminApplication
ServiceAdminApplication.java
package com.suntong.hello.spring.cloud.service.admin;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
@SpringBootApplication
@EnableEurekaClient
public class ServiceAdminApplication {
public static void main(String[] args) {
SpringApplication.run(ServiceAdminApplication.class, args);
}
}
application.yml
spring:
application:
name: hello-spring-cloud-service-admin
server:
port: 8762
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
运行入口类
先启动服务端,再启动客户端
再下main工具栏service中点击
就可以启动run Dashboard
然后按顺序启动服务
服务注册与发现
新建controller提供服务
package com.suntong.hello.spring.cloud.service.admin.controller;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class AdminController {
@Value("${server.port}")
private String port;
@RequestMapping(value = "hi", method = RequestMethod.GET)
public String sayHi(String message){
return String.format("Hi your message is : %s port : %s", message, port);
}
}
重启,访问
创建服务消费者(Ribbon)
概述
在微服务架构中,业务都会被拆分成一个独立的服务,服务与服务的通讯是基于 http restful 的。Spring cloud 有两种服务调用方式,一种是 ribbon + restTemplate,另一种是 feign。在这一篇文章首先讲解下基于 ribbon + rest。
Ribbon 简介
Ribbon 是一个负载均衡客户端,可以很好的控制 http 和 tcp 的一些行为
构建项目
pom.xml
4.0.0
com.suntong
hello-spring-cloud-dependencies
1.0.0-SNAPSHOT
../hello-spring-cloud-dependencies/pom.xml
hello-spring-cloud-web-admin-ribbon
jar
hello-spring-cloud-web-admin-ribbon
http://www.suntong.com
2019-Now
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-tomcat
org.springframework.boot
spring-boot-starter-thymeleaf
org.springframework.boot
spring-boot-starter-actuator
org.springframework.boot
spring-boot-starter-test
test
org.springframework.cloud
spring-cloud-starter-netflix-eureka-server
org.springframework.cloud
spring-cloud-starter-netflix-ribbon
net.sourceforge.nekohtml
nekohtml
org.springframework.boot
spring-boot-maven-plugin
com.suntong.hello.spring.cloud.web.admin.ribbon.WebAdminRibbonApplication
入口类
package com.suntong.hello.spring.cloud.web.admin.ribbon;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient
public class WebAdminRibbonApplication {
public static void main(String[] args) {
SpringApplication.run(WebAdminRibbonApplication.class, args);
}
}
application.yml
spring:
application:
name: hello-spring-cloud-web-admin-ribbon
thymeleaf:
cache: false
mode: LEGACYHTML5
encoding: UTF-8
servlet:
content-type: text/html
server:
port: 8764
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
配置注入 RestTemplate 的 Bean,并通过 @LoadBalanced 注解表明开启负载均衡功能
package com.suntong.hello.spring.cloud.web.admin.ribbon.config;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
@Configuration
public class RestTemplateConfiguration {
@Bean
@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
再run - edit configuration里勾选上同时运行,模拟负载均衡效果
修改端口为空着的8763
在入口类再次启动
再次访问
创建测试用的 Service
package com.suntong.hello.spring.cloud.web.admin.ribbon.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
@Service
public class AdminService {
@Autowired
private RestTemplate restTemplate;
public String sayHi(String message) {
return restTemplate.getForObject("http://hello-spring-cloud-service-admin/hi?message=" + message, String.class);
}
}
创建测试用的 Controller
package com.suntong.hello.spring.cloud.web.admin.ribbon.controller;
import com.suntong.hello.spring.cloud.web.admin.ribbon.service.AdminService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class AdminController {
@Autowired
private AdminService adminService;
@RequestMapping(value = "hi", method = RequestMethod.GET)
public String sayHi(String message){
return adminService.sayHi(message);
}
}
运行服务消费者
访问
刷新
两台服务提供者工作,负载均衡
此时Eureka上两台服务提供者,一台服务消费者
此时的架构
- 一个服务注册中心,Eureka Server,端口号为:
8761
-
service-admin
工程运行了两个实例,端口号分别为:8762
,8763
-
web-admin-ribbon
工程端口号为:8764
-
web-admin-ribbon
通过RestTemplate
调用service-admin
接口时因为启用了负载均衡功能故会轮流调用它的8762
和8763
端口
创建服务消费者(Feign)
概述
Feign 是一个声明式的伪 Http 客户端,它使得写 Http 客户端变得更简单。使用 Feign,只需要创建一个接口并注解。它具有可插拔的注解特性,可使用 Feign 注解和 JAX-RS 注解。Feign 支持可插拔的编码器和解码器。Feign 默认集成了 Ribbon,并和 Eureka 结合,默认实现了负载均衡的效果
Feign 采用的是基于接口的注解
Feign 整合了 ribbon
创建服务消费者
项目结构
pom.xml
4.0.0
com.suntong
hello-spring-cloud-dependencies
1.0.0-SNAPSHOT
../hello-spring-cloud-dependencies/pom.xml
hello-spring-cloud-web-admin-feign
jar
hello-spring-cloud-web-admin-feign
http://www.suntong.com
2019-Now
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-tomcat
org.springframework.boot
spring-boot-starter-thymeleaf
org.springframework.boot
spring-boot-starter-actuator
org.springframework.boot
spring-boot-starter-test
test
org.springframework.cloud
spring-cloud-starter-netflix-eureka-server
org.springframework.cloud
spring-cloud-starter-openfeign
net.sourceforge.nekohtml
nekohtml
org.springframework.boot
spring-boot-maven-plugin
com.suntong.hello.spring.cloud.web.admin.feign.WebAdminFeignApplication
入口类
package com.suntong.hello.spring.cloud.web.admin.feign;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class WebAdminFeignApplicatin {
public static void main(String[] args) {
SpringApplication.run(WebAdminFeignApplicatin.class, args);
}
}
配置文件application.yml
spring:
application:
name: hello-spring-cloud-web-admin-feign
thymeleaf:
cache: false
mode: LEGACYHTML5
encoding: UTF-8
servlet:
content-type: text/html
server:
port: 8765
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
创建 Feign 接口
package com.suntong.hello.spring.cloud.web.admin.feign.service;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@FeignClient(value = "hello-spring-cloud-service-admin")
public interface AdminService {
@RequestMapping(value = "hi", method = RequestMethod.GET)
public String sayHi(String message);
}
创建测试用的 Controller
package com.suntong.hello.spring.cloud.web.admin.feign.controller;
import com.suntong.hello.spring.cloud.web.admin.feign.service.AdminService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@Controller
public class AdminController {
@Autowired
private AdminService adminService;
@RequestMapping(value = "hi", method = RequestMethod.GET)
public String sayHi(String message){
return adminService.sayHi(message);
}
}
运行消费者
访问发生错误,但是Eureka已经注册了
405-用来访问此页面的方法不被允许
给service接口加上@RequestParam注解
package com.suntong.hello.spring.cloud.web.admin.feign.service;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
@FeignClient(value = "hello-spring-cloud-service-admin")
public interface AdminService {
@RequestMapping(value = "hi", method = RequestMethod.GET)
public String sayHi(@RequestParam(value="message") String message);
}
重新启动
还是报错,发现controller注解错误,因为要返回对象到body,要使用@RestController注解而不是@Controller
package com.suntong.hello.spring.cloud.web.admin.feign.controller;
import com.suntong.hello.spring.cloud.web.admin.feign.service.AdminService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class AdminController {
@Autowired
private AdminService adminService;
@RequestMapping(value = "hi", method = RequestMethod.GET)
public String sayHi(String message){
return adminService.sayHi(message);
}
}
重启
访问http://localhost:8765/hi?message=HelloFeign
刷新