当命令行过长
在.idea/workspaces.xml中
修改
<component name=”propertiesComponent”>
<properties name=”dynamic.classpath” value=”true” />
</component>

当命令行过长
在.idea/workspaces.xml中
修改
<component name=”propertiesComponent”>
<properties name=”dynamic.classpath” value=”true” />
</component>
spring cloud gateway 是微服务常用网关
网关转发语法
application.properties
spring.cloud.gateway.routes[0].id=url-proxy
spring.cloud.gateway.routes[0].predicates[0]=Path=/**
spring.cloud.gateway.routes[0].uri=http://www.baidu.com
spring.cloud.gateway.routes[0].order=1000000
spring.cloud.gateway.routes[1].id=eureka
spring.cloud.gateway.routes[1].predicates[0]=Host=eureka.robinluo.top
spring.cloud.gateway.routes[1].uri=http://localhost:8765
spring.cloud.gateway.routes[1].order=10000
order 越小 优先级越大
predicates 语法:
After=2018-01-20T06:06:06+08:00[Asia/Shanghai]
请求时间过滤 之后
Before=2018-01-20T06:06:06+08:00[Asia/Shanghai]
请求时间过滤 之前
Between=2018-01-20T06:06:06+08:00[Asia/Shanghai], 2019-01-20T06:06:06+08:00[Asia/Shanghai]
请求时间之间
Cookie=ityouknow, kee.e
cookie 匹配
Header=X-Request-Id, \d+
header 匹配
Host=**.ityouknow.com
域名匹配
Method=GET
请求方式匹配
Path=/foo/{segment}
访问路径匹配
Query=smile
请求参数匹配
RemoteAddr=192.168.1.1/24
ip地址匹配
代码分析
所有predicate 都是继承自org.springframework.cloud.gateway.handler.predicate.RoutePredicateFactory 接口的实现类
After = AfterRoutePredicateFactory
Before = BeforeRoutePredicateFactory
Between = BetweenRoutePredicateFactory
Cookie = CookieRoutePredicateFactory
Header = HeaderRoutePredicateFactory
Host = HostRoutePredicateFactory
Method = MethodRoutePredicateFactory
Path = PathRoutePredicateFactory
ReadBody = ReadBodyRoutePredicateFactory
Query = QueryRoutePredicateFactory
RemoteAddr = RemoteAddrRoutePredicateFactory
Weight = WeightRoutePredicateFactory
PredicateSpec 有所有配置语法
服务发现是 服务治理的一个很重要的点
所有注册在服务平台的微服务 必须要能被发现 然后调用
而我们调用其他服务一般有三种方法
DiscoverClient ribbon Feign
DiscoverClient 是更加低层的方法 当DiscoverClient 需要寻找服务时 其实是向服务注册器(例如 eureka) 发送 http 请求获取躯体服务信息 包括 ip port 等
@SpringBootApplication
@EnableDiscoveryClient
class Application {
@Autowired
DiscoveryClient discoveryClient
}
添加了注解@EnableDiscoveryClient
然后就能自动 注入 discoverClient
@Autowired
DiscoveryClient discoveryClient
def restTemplate = new RestTemplate()
def serverList = discoveryClient.getInstances("ROBIN-ADMIN")
println(serverList)
restTemplate.getForObject("${serverList[0].getUri()}/api/ribbon",Map.class)
获取到discoverClient 就能通过 服务名字 查找服务实例 并且通过RestTemplate 调用服务接口了
Ribbon是调用了 discoverClient 调用服务的 但是他提供了 负载均衡功能,不显式调用某个服务实例 而是通过策略调用某类服务的其中一个 达到负载均衡效果
@SpringBootApplication
class RibbonApplication {
@Bean
@LoadBalanced
RestTemplate restTemplate() {
return new RestTemplate()
}
}
在注册RestTemplate对象时 添加LoadBalanced 注解
LoadBalanced 会自动实例化restTemplate 的服务均衡策略 具体查看LoadBalance接口 会定时ping各个服务实例 也会用譬如 回环轮询策略 寻找服务实例
当restTemplate 调用服务时 通过策略调用服务实例
restTemplate.getForObject("http://ROBIN-ADMIN/api/health",Map.class)
ROBIN-ADMIN 为某类服务的服务ID
Feign 是更加接近业务的服务调用方式
maven 添加依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
添加Feign注解
@EnableFeignClients
class RibbonApplication {
}
新建接口对象
package org.robin.ribbon.feign
import org.springframework.cloud.openfeign.FeignClient
import org.springframework.web.bind.annotation.RequestMapping
@FeignClient("ROBIN-ADMIN")
interface RobinAdminService {
@RequestMapping("/api/ribbon")
Map ribbon()
@RequestMapping("/api/health")
Map health()
}
spring会自动生成 RobinAdminService
调用该对象的方法 可以 调用对应微服务的接口
作为微服务服务注册供应方
默认在本机 http://localhost:8761/eureka/提供服务
注册请求地址在 apps/{service-name} POST 发送本机服务信息
注销请求地址在 apps/{service-name}/{id} DELETE 发送请求
心跳请求地址在 apps/{service-name}/{id} PUT 发送请求
状态请求地址在 apps/{service-name}/{id}/status PUT 发送请求
删除状态请求地址在 apps/{service-name}/{id}/status DELETE 发送请求
断路器 用作监控请求 是否合理 当出现异常流量 可以短路保护
具体使用方式通过切面编程 将需要监控的方法 包括controller service dao 的方法添加注解方式
然后当执行该方法时 会先进去hystrix定义的监控线程上
异步执行需监控的方法 并注册一个超时事件在 监控线程上
所以被HystrixCommand 注解的方法其实是异步执行的
思考 是否应该在网关应用上 添加hystrix 做断路器限流
的确是应该如此这样做
Spring Cloud Netflix Sidecar框架提供了Sidecar模式的现成解决方案。Spring Cloud Netflix Sidecar框架框架可以提供对其他非Spring Cloud技术栈的微服务的治理。比如,你可以使用Node或者Golang php 编写一个Web项目,这个服务同样可以以Sidecar模式,纳入到Spring Cloud管理中去。
类似于数据管道处理的 框架 是一个面向数据的框架
可以兼容多种现有的消息处理框架 包括kafka MQ 等 也可以处理 java 特有JMS消息 RMI Socket 等数据接入点
核心信息用Message 代表
Channel 发送信息 send 拉取信息 receive 订阅消息 subscribe
queue channel 可以缓冲消息
channel interceptor 拦截器了 说明消息处理也是过滤链模式
channel.addInterceptor(Interceptor xxx)
xml 配置说明
spring-integration 可通过xml配置消息处理链 达到代码解耦效果
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.5</version>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>robin.tcpip.gateway.Main</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
mainClass 指定 可执行主类
执行 mvn package 可打包
打包成runnable jar 后可直接运行 且保内包含所有依赖的jar包
zuul 网关应用分 1.X 版本 和 2.X 版本 两者相差很大
以下详细说明zuul 1.X 版本
在原始在zuul-core 包中 所有请求是通过 com.netflix.zuul.http.ZuulServlet 在 /zuul/* 下建立servlet 入口
然后在 zuulServlet的service方法中 执行 zuulRunner 去处理请求
然后不同请求路径下会使用 zuulRunner里面的不同的 filterProcessor 去处理
譬如 :
静态路由的地址 由配置文件配置的路由器处理
微服务路由地址 由ribbon的提供路由策略 RibbonRoutingFilter
所有的这些处理请求filter 其实是把请求重发到对应的地址
再把响应结果返回给网关(转发)
具体实现http请求的框架可以配置 okhttp httpClient 等
和 spring-boot 整合后
springmvc 用 org.springframework.cloud.netflix.zuul.web.ZuulController
包装了zuulServlet (servletWrapper)
还是通过springMVC去处理网关!!!
mycat配置解释
再mycat2/conf/有配置文件
server.xml 定义数据库连接 用户
schema.xml 定义 虚拟表和实体表
rule.xml 定义分库逻辑(入库)
route.xml定义查询时实体表路由配置(查询)
简单按字段值分库
<!-- 按照学校名分表 -->
<tableRule name="shardingBySchoolName">
<rule>
<columns>school_name</columns>
<algorithm>shardingBySchoolName</algorithm>
</rule>
</tableRule>
<!-- 按照学校名分表 -->
<function name="shardingBySchoolName" class="org.opencloudb.route.function.PartitionByFileMap">
<property name="mapFile">shardingBySchoolName.txt</property>
<property name="type">1</property>
<property name="defaultNode">0</property>
</function>
shardingBySchoolName.txt
爱享=0
中悦=1
DEFAULT_NODE=1