注:整合eureka参考
一,项目结构
二,父工程 pom文件
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>xyz.tulling</groupId>
<artifactId>springcloud</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<modules>
<module>product_service</module>
<module>order_service</module>
<module>eureak_server</module>
</modules>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
</parent>
<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-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.4</version>
<scope>provided</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Greenwich.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<repositories>
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>http://repo.spring.io/libs-snapshot-local</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>http://repo.spring.io/libs-milestone-local</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>spring-releases</id>
<name>Spring Releases</name>
<url>http://repo.spring.io/libs-release-local</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>http://repo.spring.io/libs-snapshot-local</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</pluginRepository>
<pluginRepository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>http://repo.spring.io/libs-milestone-local</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
三,eureka注册中心配置
1,·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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>springcloud</artifactId>
<groupId>xyz.tulling</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>eureak_server</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
</project>
2,application.yml配置文件
server:
port: 9000
eureka:
instance:
hostname: localhost
client:
register-with-eureka: false # 是否将自己注册到注册中心
fetch-registry: false # 是否从eureka获取注册的信息
# 配置暴露给eureka client的请求地址
service-url:
default-zone: http://${eureka.instance.hostname}:${server.port}/eureka/
3,启动类
package xyz.tulling.eureka;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@SpringBootApplication
@EnableEurekaServer
public class EurekaApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaApplication.class, args);
}
}
4,遇到的问题
springboot和springcloud的版本是一一对应的,如果版本不对应会依赖冲突
2,springboot1.5.0以及之前的版本服务端和客户端的依赖包写法不同
服务端
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
</dependency>
客户端
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
四,客户端配置(服务)
1,pom.xml
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
2,application.yml
server:
port: 9001
spring:
application:
name: service-product
eureka:
client:
service-url:
defaultZone: http://localhost:9000/eureka
instance:
prefer-ip-address: true # 使用IP地址注册
3,启动器
@SpringBootApplication
@EntityScan("xyz.tulling.product.entity")
@EnableEurekaClient
public class ProductApplication {
public static void main(String[] args) {
SpringApplication.run(ProductApplication.class, args);
}
}
五,客户端配置(服务消费者)
1,pom.xml
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
2,application.xml
server:
port: 9002
spring:
application:
name: service-order
eureka:
client:
service-url:
defaultZone: http://localhost:9000/eureka
instance:
prefer-ip-address: true # 使用IP地址注册
3,启动器
@SpringBootApplication
@EntityScan("xyz.tulling.order.entity")
public class OrderApplication {
/**
* 使用Spring提供的RestTemplate发送http请求到商品服务
* 1. 创建RestTemplate对象交给容器管理
* 2. 在使用的时候,调用其方法完成操作
*/
@LoadBalanced
@Bean
public RestTemplate getRestTemplate() {
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class, args);
}
}
4,对服务的调用
利用了ribbon进行客户端负载均衡时直接拼接服务名,如下:
product = restTemplate.getForEntity(“http://service-product/product/” + id,
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import xyz.tulling.order.entity.Product;
import javax.xml.ws.Service;
import java.util.List;
@RestController
@RequestMapping("/order")
public class OrderController {
@Autowired
RestTemplate restTemplate;
@Autowired
private DiscoveryClient discoveryClient;
@RequestMapping(value = "/buy/{id}", method = RequestMethod.GET)
public Product findById(@PathVariable Long id) {
List<ServiceInstance> instances = discoveryClient.getInstances("service-product");
//ServiceInstance instance = instances.get(0);
Product product = null;
product = restTemplate.getForEntity("http://service-product/product/" + id, Product.class).getBody();
return product;
}
}
5,关于ribbon负载均衡
简介:
Spring Cloud Ribbon是一个基于HTTP和TCP的客户端负载均衡工具,它基于Netflix
Ribbon实现。通过Spring Cloud的封装,可以让我们轻松地将面向服务的REST模版请求自
动转换成客户端负载均衡的服务调用。==Spring Cloud Ribbon虽然只是一个工具类框架,
它不像服务注册中心、配置中心、API网关那样需要独立部署,但是它几乎存在于每一个
Spring Cloud构建的微服务和基础设施中。==因为微服务间的调用,API网关的请求转发等
内容,实际上都是通过Ribbon来实现的,包括后续我们将要介绍的Feign,它也是基Ribbon
实现的工具。所以,对Spring Cloud Ribbon的理解和使用,对于我们使用Spring Cloud来构
建微服务非常重要。
使用
通过Spring Cloud Ribbon的封装,我们在微服务架构中使用客户端负载均衡调用非常简单,只需要如下两步:
▪️服务提供者只需要启动多个服务实例并注册到一个注册中心或是多个相关联的服务注册中心。
▪️服务消费者直接通过调用被@LoadBalanced注解修饰过的RestTemplate来实现面向服务的接口调用。