# microservice
**Repository Path**: lan_nan/microservice
## Basic Information
- **Project Name**: microservice
- **Description**: 微服务
- **Primary Language**: Java
- **License**: Apache-2.0
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2022-10-02
- **Last Updated**: 2022-10-03
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# microservice
## 介绍
搭建微服务架构
码云:https://gitee.com/lan_nan/microservice/tree/master/
码云克隆:https://gitee.com/lan_nan/microservice.git
## 软件架构
聚合项目
microservice 管理个个模块
- common 公共模块,用来存放共有的对象和jar包
- consumer 消费者模块
- provider 提供者模块
- gateway 网关模块
## 项目搭建过程
### 1.开启nacos服务
官网:https://nacos.io/zh-cn/docs/quick-start.html
#### 1-1.配置
点击运行配置


添加一个Shell Script


出现这个运行一下

#### 1-2.测试
运行起来没报错就成功了

### 2.搭建注册中心nacos
#### 2-1.common
```xml
microservice
com.lan.mall
0.0.1-SNAPSHOT
4.0.0
common
8
8
org.springframework.boot
spring-boot-dependencies
2.3.2.RELEASE
pom
import
org.springframework.cloud
spring-cloud-dependencies
Hoxton.SR9
pom
import
com.alibaba.cloud
spring-cloud-alibaba-dependencies
2.2.6.RELEASE
pom
import
com.baomidou
mybatis-plus-boot-starter
3.3.1.tmp
mysql
mysql-connector-java
org.springframework.boot
spring-boot-starter-web
org.projectlombok
lombok
org.springframework.boot
spring-boot-starter-test
org.junit.jupiter
junit-jupiter-engine
com.alibaba
fastjson
1.2.60
compile
com.alibaba.cloud
spring-cloud-starter-alibaba-nacos-discovery
org.springframework.cloud
spring-cloud-starter-openfeign
com.alibaba.cloud
spring-cloud-starter-alibaba-nacos-config
org.apache.httpcomponents
httpclient
4.5.8
org.apache.maven.plugins
maven-compiler-plugin
3.8.1
8
8
```
#### 2-2.consumer、provider
```xml
4.0.0
com.lan.mall
模块名称
0.0.1-SNAPSHOT
模块名称
模块名称
1.8
com.lan.mall
模块名称
0.0.1-SNAPSHOT
org.springframework.boot
spring-boot-maven-plugin
```
gateway的pom文件
```xml
4.0.0
com.lan.mall
gateway
0.0.1-SNAPSHOT
gateway
gateway
1.8
org.springframework.cloud
spring-cloud-dependencies
Hoxton.SR9
pom
import
com.alibaba.cloud
spring-cloud-alibaba-dependencies
2.2.6.RELEASE
pom
import
com.lan.mall
common
0.0.1-SNAPSHOT
com.baomidou
mybatis-plus-boot-starter
org.springframework.boot
spring-boot-starter-web
org.springframework.cloud
spring-cloud-starter-gateway
com.alibaba.cloud
spring-cloud-starter-alibaba-nacos-discovery
com.alibaba.cloud
spring-cloud-starter-alibaba-sentinel
com.alibaba.cloud
spring-cloud-alibaba-sentinel-gateway
io.netty
netty-codec-http
4.1.31.Final
org.springframework.boot
spring-boot-maven-plugin
```
#### 2-3.yml文件
```yaml
# consumer、provider、gateway都要配置
#配置端口号
server:
port: 端口号,不能一致
spring:
application: #链接--------nacos
name: 命名,不能一致 #服务注册时,服务名必须配置
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848 # nacos注册中心地址 从哪里去查找服务
config:
server-addr: 127.0.0.1:8848 # nacos配置中心地址
enabled: false #关闭报错
```
consumer、provider再写入以下内容:
```yaml
# mybatis-plus根据模块是否需要再加,gateway就不需要
datasource:
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://lcalhost:3306/microservice?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
mybatis-plus:
mapper-locations: classpath:/mapper/**/*.xml
global-config:
db-config:
id-type: auto
```
consumer再写入以下内容:
```yaml
# 配置到consumer,消费者下,实现负载均衡
# sca-provider服务负载均衡配置 赋予服务提供方策略
sca-provider:
ribbon: #负载均衡组件,是ribbon组件提供了Irule接口及相关实现
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
feign:
hystrix:
enabled: true #打开熔断机制,如果调用不到启动备选方案
```
将consumer和provider运行后在nacos网站上能看到服务名称(服务名称就是spring.application.name=?)
nacos网站:http://localhost:8848/nacos/ 用户名和密码都是nacos

### 3.创建hello接口
我在common下创建一个User对象和一个响应的工具R,还有响应数据的枚举型REnum
#### 3-1.创建类
```java
package com.lan.mall.common.bean;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private Integer id;
private String name;
private Integer age;
}
```
```java
package com.lan.mall.common.utils;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class R {
private Integer code;
private String massage;
private Object data;
public static R success(){
return new R(REnum.SUCCESS.getCode(), REnum.SUCCESS.getMassage(), null);
}
public static R success(Object data){
return new R(REnum.SUCCESS.getCode(), REnum.SUCCESS.getMassage(), data);
}
public static R error(){
return new R(REnum.ERROR.getCode(), REnum.ERROR.getMassage(), null);
}
public static R error(Object data){
return new R(REnum.ERROR.getCode(), REnum.ERROR.getMassage(), data);
}
public static R timeOut(){
return new R(REnum.TIME_OUT.getCode(), REnum.TIME_OUT.getMassage(), null);
}
}
```
```java
package com.lan.mall.common.utils;
import lombok.AllArgsConstructor;
import lombok.Getter;
@AllArgsConstructor
@Getter
public enum REnum {
// 成功
SUCCESS(200, "success")
// 失败
, ERROR(901, "error")
, TIME_OUT(902, "服务超时,请重新")
;
private final Integer code;
private final String massage;
}
```
在provider在创建providerHello接口创建
```java
package com.lan.mall.provider.controller;
import com.lan.mall.common.bean.User;
import com.lan.mall.common.utils.R;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/user")
@RefreshScope
public class UserController {
@RequestMapping("/getUser")
public R getUser(@RequestParam(required = false, value = "appName") String appName){
return R.success(new User(1, appName, 20));
}
@RequestMapping("/hello")
public R providerHello(){
return R.success("providerHello");
}
}
```
#### 3-2.测试

### 4.openFeign
在consumer模块的启动类下创建RestTemplate对象并进行负载均衡、yml文件配置Ribbon提供负载均衡和重试的功能
#### 4-1.RestTemplate
```java
package com.lan.mall.consumer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScans;
import org.springframework.web.client.RestTemplate;
@SpringBootApplication
@EnableFeignClients
// 配置这个扫描包,是因为有feign下的一个类一直没加载,导致启动时报错
@ComponentScans(value = {
@ComponentScan("com.lan.mall.consumer.controller"),
@ComponentScan("com.lan.mall.consumer.feign")
})
public class ConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumerApplication.class, args);
}
@Bean
@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
```
```yaml
#sca-provider服务负载均衡配置 赋予服务提供方策略
sca-provider:
ribbon: #负载均衡组件,是ribbon组件提供了Irule接口及相关实现
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
feign:
hystrix:
enabled: true #打开熔断机制,如果调用不到启动备选方案
```
consumer模块通过openFeign进行访问provider的访问
#### 4-2.添加Feign服务
```java
package com.lan.mall.consumer.feign;
import com.lan.mall.common.utils.R;
import com.lan.mall.consumer.hystrix.UserServiceFallBackFactory;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
/**
* value是spring.application.name的名称,contextId是自动注入的名称
* fallbackFactory是处理服务中断和超时的问题
* 需要我们进行实现
*/
@FeignClient(value = "provider", contextId = "userService", fallbackFactory = UserServiceFallBackFactory.class)
public interface UserService {
// 这个路径必须是全面的
@RequestMapping("/user/getUser")
public R getUser(@RequestParam(required = false, value = "appName") String appName);
@RequestMapping("/user/hello")
public R providerHello();
}
```
fallbackFactory的实现:
```java
package com.lan.mall.consumer.hystrix;
import com.lan.mall.common.utils.R;
import com.lan.mall.consumer.feign.UserService;
import feign.hystrix.FallbackFactory;
import org.springframework.stereotype.Component;
@Component
public class UserServiceFallBackFactory implements FallbackFactory {
@Override
public UserService create(Throwable throwable) {
return new UserService() {
@Override
public R getUser(String appName) {
return R.timeOut();
}
@Override
public R providerHello() {
return R.timeOut();
}
};
}
}
```
#### 4-3.消费者的接口
```java
package com.lan.mall.consumer.controller;
import com.lan.mall.common.utils.R;
import com.lan.mall.consumer.feign.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@RestController
@RequestMapping("/consumer")
@Slf4j
public class ConsumerController {
@Value("${spring.application.name:consumer}")
String appName;
// openFeign的服务
@Autowired
private UserService userService;
// 负载均衡访问服务
@Autowired
private RestTemplate restTemplate;
/**
* 通过负载均衡访问提供者服务的getUser接口
*/
@RequestMapping("/getUser")
public R getUser(){
String url = String.format("http://provider/user/getUser?appName=%S", appName);
return restTemplate.getForObject(url, R.class);
}
/**
* 通过远程调用接口,访问hello服务
*/
@RequestMapping("/consumerHello")
public R consumerHello(){
R r = userService.providerHello();
r.setData(r.getData() + " consumerHello");
return r;
}
}
```
#### 4-4.测试


### 5.gateway
#### 5-1.配置
```yaml
spring:
application:
name: gateway #通过网关进行访问。
cloud:
nacos:
discovery: #服务注册端口
server-addr: localhost:8848
config: #配置中心端口
server-addr: localhost:8848
file-extension: yml #配置文件后缀名
sentinel: #配置限流端口
transport:
dashboard: localhost:8180
eager: true #开启通过服务注册中心的serbiceId创建路由
gateway:
routes: #路由
- id: router01 #资源服务路由名称
uri: lb://provider #lb表示负载均衡 后面是需要进行负载均衡的服务名
predicates: #匹配规则
- Path=/provider/** #设置访问路径 以及规则
filters:
- StripPrefix=1
- id: router02 #认证服务路由名称
uri: lb://consumer #lb表示负载均衡 后面是需要进行负载均衡的服务名
predicates: #谓词对象,可以定义多个谓词逻辑
- Path=/consumer/**
filters:
- StripPrefix=1 #去掉第一层路径
globalcors: #跨域配置(写到配置文件的好处是可以将其配置写到配置中心)
corsConfigurations: #所有跨域配置只是针对ajax请求,因为ajax请求不支持跨域
'[/**]':
allowedOrigins: "*"
allowedHeaders: "*"
allowedMethods: "*"
allowCredentials: true
logging: #日志
level:
org.springframework.cloud.gateway: debug
```
#### 5-2.测试


## springcloud的理解
springcloud就相当于将很多的接口进行细分,分成一个个模块,就比如将一个商城分为订单模块、商品模块、会员模块、仓库模块、管理员模块等,然后将这些服务分布到个个服务器上进行运行,这样可以减小服务器的压力,并且好维护,但是需要的服务器相对较多,运维难道加大
## 注册中心的作用
服务注册中心的作用就是服务的注册和服务的发现
服务注册,就是将提供某个服务的模块信息注册到1个公共的组件上去。
服务发现,就是新注册的这个服务模块能够及时的被其他调用者发现,不管是服务新增和服务删减都能实现自动发现。
## 配置中心的作用
配置中心就是将配置从各个应用中的配置文件拿出来,对所有的配置进行单独的统一管理。配置中心是整个微服务基础架构体系中的一个组件。总得来说,配置中心就是一种统一管理各种应用配置的基础服务组件。
## 网关的作用
网关是一种充当转换重任的计算机系统或设备,在使用不同的通信协议,数据格式或语言,甚至体系结构完全不同的两种系统时,网关是一个翻译器。与网桥只是简单地传送信息不同,网关对收到的信息要重新打包,以适应目的系统的需求。同时,网关也可以提供过滤和安全功能。
## 什么是负载均衡
负载均衡就是将一个相同的服务放在不同的服务器下,通过负载均衡算法进行分配访问。