目录
1.1 HTTP的RESTful接口以及基于TCP的RPC协议 的区别与联系
1、 微服务的问题及一些解决方案
1.1 HTTP的RESTful接口以及基于TCP的RPC协议 的区别与联系
2 创建父工程
(1)创建springboot
(2)导入依赖
<!--dependencyManagement:它只负责jar的版本号管理,不负责jar的下载,交于子模块,子模块在使用时无需指定版本号
:springboot springcloud springcloudalibaba之间版本一定要匹配
-->
<!--定义版本号-->
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF- 8</project.reporting.outputEncoding>
<spring-cloud.version>Hoxton.SR8</spring-cloud.version>
<spring-cloud-alibaba.version>2.2.3.RELEASE</spring-cloud-alibaba.version>
</properties>
<!--dependencyManagement:它只负责jar的版本号管理,不负责jar的下载,交于子模块,子模块在使用时无需指定版本号
:springboot springcloud springcloudalibaba之间版本一定要匹配
-->
<dependencyManagement>
<dependencies>
<!--springcloud的版本管理-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--springcloudalibaba的版本管理-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring-cloud-alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
3、创建基础模块
(1) 创建 shop-common 模块,在pom.xml中添加依赖
(2)依赖
<dependencies> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.5.1</version> </dependency> </dependencies>
(3)创建实体类(在微服务中共用)
略
3.1 创建其他模块
(1)导入依赖(跟上面的创建一样)
<dependencies> <!--引入公共模块--> <dependency> <artifactId>springcloud_parent</artifactId> <groupId>com.wk</groupId> <version>0.0.1-SNAPSHOT</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> </dependencies>
(2) 创建的主类
(3)创建配置类
4订单微服务
(1)创建与上面过程一样
(2)controller类
package com.wk.order.controller;
import com.wk.entity.Order;
import com.wk.entity.Product;
import com.wk.order.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@RestController
@RequestMapping("order")
public class OrederController {
@Autowired
private OrderService orderService;
//该类默认没有交于spring管理----->
@Autowired
private RestTemplate restTemplate;
@GetMapping("getBuy/{pid}/{num}")
public String getBuy(@PathVariable Integer pid,@PathVariable Integer num){
System.out.println("=====================采购=========================");
Order order = new Order();
order.setNumber(num);
//用户的信息可以根据token从redis中获取用户信息
order.setUid(1);
order.setUsername("张三");
//需要设置订单对象中商品的信息
//商品操作都在商品微服务---订单微服务远程调用商品微服务即可拿到商品信息。远程调用:http协议的restFul风格调用适合微服务, 基于TCP协议的RPC调用适合SOA分布式
//一定采用的为http协议: (1)自己写代码完成http调用【httpclient】微信支付 ---适合调用第三方网址。 (2)spring提高了一个工具类RestTemplate,该类也是基于http协议完成的调用
Product product = restTemplate.getForObject("http://localhost:8081/product/getp/"+pid,Product.class);
System.out.println("~~~~~~~~~~~~~远程查询的商品结果+================"+product);
order.setPid(product.getPid());
order.setPname(product.getPname());
order.setPprice(product.getPprice());
orderService.saveOrder(order);
return "采购完成";
}
}
(3)RestTemplate的配置
5、错误
Error:(3, 32) java: 程序包org.springframework.boot不存在
Error:(4, 46) java: 程序包org.springframework.boot.autoconfigure不存在
Error:(6, 2) java: 找不到符号
符号: 类 SpringBootApplication
Error:(10, 9) java: 找不到符号
符号: 变量 SpringApplication
位置: 类 com.wk.SpringcloudParent2Application
(1)解决办法
将父工程下的src删除,即可解决问题
6、注册中心
Zookeeper
zookeeper是一个分布式服务框架,是Apache Hadoop 的一个子项目,它主要是用来解决分布式
应用中经常遇到的一些数据管理问题,如:统一命名服务、状态同步服务、集群管理、分布式应用
配置项的管理等。
Eureka
Eureka是Springcloud Netflix中的重要组件,主要作用就是做服务注册和发现。但是现在已经闭
源 ,停更不停用。
Consul
Consul是基于GO语言开发的开源工具,主要面向分布式,服务化的系统提供服务注册、服务发现
和配置管理的功能。Consul的功能都很实用,其中包括:服务注册/发现、健康检查、Key/Value
存储、多数据中心和分布式一致性保证等特性。Consul本身只是一个二进制的可执行文件,所以
安装和部署都非常简单,只需要从官网下载后,在执行对应的启动脚本即可。
Nacos (服务治理 配置中心)
Nacos是一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。它是 Spring
Cloud Alibaba 组件之一,负责服务注册发现和服务配置,可以这样认为nacos=eureka+config。
6.1 Nacos的使用
第1步: 安装nacos
下载地址: https://github.com/alibaba/nacos/releases
下载zip格式的安装包,然后进行解压缩操作
第2步: 启动nacos
#切换目录
cd nacos/bin
#命令启动
startup.cmd -m standalone
然后在命令提示符中输入启动命令
第三步 访问nacos
打开浏览器输入http://localhost:8848/nacos,即可访问服务, 默认密码是nacos/nacos
6.2 将微服务注册到nacos
1 在你要注册到nacos的微服务中的pom.xml中添加nacos的依赖
6.2.1 将商品微服务注册到nacos
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
2、在application.porperties添加nacos的配置
#微服务的注册 spring.cloud.nacos.discovery.server-addr=localhost:8848 #wk-product是你为注册到nacos中起的微服务名字 spring.application.name=shop-product
3、 启动商品微服务
这是注册成功后的显示
判断是否将该服务注册到注册中心
如果为true就不会注册
6.2.2 将订单微服务注册到nacos中
1 在pom.xml中添加nacos的依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-nacos-discovery</artifactId>
</dependency>
2、在application.porperties添加nacos的配置
#微服务的注册 spring.cloud.nacos.discovery.server-addr=localhost:8848 #判断是否件该服务注册到nacos中 spring.cloud.nacos.discovery.register-enabled=false spring.application.name=wk-order
3、对controller层的代码进行修改
package com.wk.order.controller;
import com.wk.entity.Order;
import com.wk.entity.Product;
import com.wk.order.fei.ProductFei;
import com.wk.order.service.OrderService;
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.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import java.util.List;
import java.util.Random;
@RestController
@RequestMapping("order")
public class OrederController {
@Autowired
private OrderService orderService;
//该类默认没有交于spring管理----->
@Autowired
private RestTemplate restTemplate;
@Autowired
private DiscoveryClient discoveryClient;
@GetMapping("getBuy/{pid}/{num}")
public String getBuy(@PathVariable Integer pid,@PathVariable Integer num){
System.out.println("=====================采购=========================");
Order order = new Order();
order.setNumber(num);
//用户的信息可以根据token从redis中获取用户信息
order.setUid(1);
order.setUsername("张三");
// //根据服务名获取对应的所有实例对象
List<ServiceInstance> instances = discoveryClient.getInstances("wk-product");
//获取第一个实例对象
ServiceInstance serviceInstance = instances.get(0);
//获取实例对象的http+ip+port
String path = serviceInstance.getUri().toString();
//需要设置订单对象中商品的信息
//商品操作都在商品微服务---订单微服务远程调用商品微服务即可拿到商品信息。远程调用:http协议的restFul风格调用适合微服务, 基于TCP协议的RPC调用适合SOA分布式
//一定采用的为http协议: (1)自己写代码完成http调用【httpclient】微信支付 ---适合调用第三方网址。 (2)spring提高了一个工具类RestTemplate,该类也是基于http协议完成的调用
Product product = restTemplate.getForObject(path+"/product/getp/"+pid,Product.class);
System.out.println("~~~~~~~~~~~~~远程查询的商品结果+================"+product);
order.setPid(product.getPid());
order.setPname(product.getPname());
order.setPprice(product.getPprice());
orderService.saveOrder(order);
return "采购完成";
}
}
7、负载均衡
7.1 自定义实现负载均衡
1 通过idea再启动一个 shop-product 微服务,设置其端口为8082
在RestTemplate上添加@LoadBalanced
然后,只修改订单微服务中的controller中代码的一行,修改后的结果
7.2 Ribbon支持的负载均衡策略
随机选择一个server
在订单微服务中的application.porperties添加
#指定ribbon负载军衡器的策略:springcloud-product微服务名称.ribbon.NFLoadBalancerRuleClassName=负载均衡策略 wk-product.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule
8、基于OpenFeign实现服务调用
OpenFeign是Spring Cloud提供的一个声明式的伪Http客户端, 它使得调用远程服务就像调用本地服务一样简单, 只需要创建一个接口并添加一个注解即可。
8.1 Feign的使用
1 加入Fegin的依赖
<!--feign的jar文件-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
2 在主启动类上加入开启feign的注解
3 创建feign的接口
4 修改OrderController的代码
package com.wk.order.controller;
import com.wk.entity.Order;
import com.wk.entity.Product;
import com.wk.order.fei.ProductFei;
import com.wk.order.service.OrderService;
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.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import java.util.List;
import java.util.Random;
@RestController
@RequestMapping("order")
public class OrederController {
@Autowired
private OrderService orderService;
//该类默认没有交于spring管理----->
@Autowired
private RestTemplate restTemplate;
@Autowired
private DiscoveryClient discoveryClient;
@Autowired(required = false)
private ProductFei productFei;
@GetMapping("getBuy/{pid}/{num}")
public String getBuy(@PathVariable Integer pid,@PathVariable Integer num){
System.out.println("=====================采购=========================");
Order order = new Order();
order.setNumber(num);
//用户的信息可以根据token从redis中获取用户信息
order.setUid(1);
order.setUsername("张三");
//获取商品的相关信息
Product product = productFei.getProduct(pid);
System.out.println("~~~~~~~~~~~~~远程查询的商品结果+================"+product);
order.setPid(product.getPid());
order.setPname(product.getPname());
order.setPprice(product.getPprice());
orderService.saveOrder(order);
return "采购完成";
}
}
9、使用eureka作为注册中心
Eureka是Netflix开发的服务发现框架,SpringCloud将它集成在自己的子项目spring-cloud-netflix中,实现SpringCloud的服务发现功能。
- 创建一个eureka服务端
2、applicaton.properties
server.port=7001
spring.application.name=eureka-server
#实例的主机名
eureka.instance.hostname=localhost
#是否把eureka服务端注册到注册中心
eureka.client.register-with-eureka=false
#该服务是否从注册中心拉取服务
eureka.client.fetch-registry=false
# 提供类微服务的地址
eureka.client.service-url.defaultZone=http://localhost:7001/eureka
3、主启动类
@SpringBootApplication
@EnableEurekaServer
public class EurekaApp {
public static void main(String[] args) {
SpringApplication.run(EurekaApp.class,args);
}
}
客户端(商品微服务和订单微服务)
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
配置文件
eureka.client.service-url.defaultZone=http://localhost:7001/eureka