接口分类
1、开放接口
通过appid+appsocet生成accessToken 进行通讯,遵循 OAuth2.0协议方式
2、内部接口
一般只能在局域网中进行访问
如何设计项目的接口?
有几个点
1开放接口和内部接口的区别
接口开发平台 auth2.0协议
2安全性 https
3网关
4实现黑名单,白名单
5restful 风格 轻量 跨平台 http+json
6实现服务保护,服务降级,熔断 ,隔离
一、网关
客户端请求统一到网关服务器,再由网关进行转发请求到实际服务器
网关作用
对请求进行权限控制、负载均衡、日志管理、接口调用监控
1、内网网关
2、外网网关
nginx 和zuul区别
相同点:都可以实现负载均衡,反向代理,过滤请求
区别:
nginx c语言 zuul负载均衡:ribbon+eureka
zk-zull-gateway
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.8.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Greenwich.SR3</spring-cloud.version>
<maven-jar-plugin.version>3.1.1</maven-jar-plugin.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- zuul网关 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zookeeper-all</artifactId>
<exclusions>
<exclusion>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.6</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
配置文件
spring.application.name=zk-zuul-gateway
server.port=9000
#只能是本地才能这么写,如果连接远程需要加bootstrap.yml,zookeeper创建的是临时节点,服务关掉后节点也会被删除
#spring.cloud.zookeeper.connect-string=localhost:2181
#当访问网关服务 以user/开头会转到zk-user服务 默认是ribbon做负载,不用再配置负载均衡
#网关服务和用户服务,会员服务在一个局域网中!!!!!!!!!!!!!
zuul.routes.api-a.path=/user/**
zuul.routes.api-a.serviceId=zk-user
zuul.routes.api-b.path=/member/**
zuul.routes.api-b.serviceId=zk-member
#hystrix.command.default.execution.timeout.enabled=true
#hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=60000
#ribbon.ReadTimeout=60000
#ribbon.ConnectTimeout=60000
#ribbon.MaxAutoRetries=0
#ribbon.MaxAutoRetriesNextServer=1
#ribbon.eureka.enabled=false
#zuul.max.host.connections=500
#zuul.host.socket-timeout-millis=60000
#zuul.host.connect-timeout-millis=60000
过滤器
/**
* zuul网关过滤器
* @author Administrator
*
*/
@Component
public class AuthenticationFilter extends ZuulFilter {
/**
* 过滤类型
*/
@Override
public String filterType() {
//fiterType,有pre、route、post、error四种类型,分别代表路由前、路由时
//路由后以及异常时的过滤器
return FilterConstants.PRE_TYPE;
}
/**
* 过滤器执行顺序,当一个请求同一个阶段有多个过滤器的时候,越小越先执行
*/
@Override
public int filterOrder() {
//排序,指定相同filterType时的执行顺序,越小越优先执行,这里指定顺序为路由过滤器的顺序-1,即在路由前执行
return FilterConstants.PRE_DECORATION_FILTER_ORDER - 1;
}
/**
* 过滤器是否生效
*/
@Override
public boolean shouldFilter() {
//是否应该调用run()方法
return true;
}
/**
* 验证业务逻辑代码
*/
@Override
public Object run() throws ZuulException {
RequestContext context = RequestContext.getCurrentContext();
HttpServletRequest request = context.getRequest();
//String token = request.getHeader("X-Authentication");
String token = request.getParameter("token");
if (StringUtils.isBlank(token)) {
//throw new TokenNotValidException("token不存在!");
//请求不会继续执行
context.setSendZuulResponse(false);
context.setResponseBody("token不存在");
}
//校验token正确性
return null;
}
}
@SpringBootApplication
/**
* 使用zookeeper 或使用connsoul时@EnableDiscoveryClient注册到注册中心
* @author Administrator
*
*/
@EnableDiscoveryClient
//开启Zuul
@EnableZuulProxy
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
zk-member
spring.application.name=zk-member
server.port=9200
#只能是本地才能这么写,如果连接远程需要加bootstrap.yml,zookeeper创建的是临时节点,服务关掉后节点也会被删除
#spring.cloud.zookeeper.connect-string=localhost:2181
#设置ribbon 读取和超时时间 默认1秒 超过1秒调用失败
ribbon.ConnectTimeout=5000
# Read timeout used by Apache HttpClient
ribbon.ReadTimeout=5000
#开启hystrix
feign.hystrix.enabled: true
#禁止hystrix超时时间设置,默认开启,1秒,如果不设置,接口调用超过1秒 会执行fallbackMethod
hystrix.command.default.execution.timeout.enabled:false
#hystrix.command.default.execution.timeout.enabled=true
#hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=60000
#ribbon.ReadTimeout=60000
#ribbon.ConnectTimeout=60000
#ribbon.MaxAutoRetries=0
#ribbon.MaxAutoRetriesNextServer=1
#ribbon.eureka.enabled=false
#zuul.max.host.connections=500
#zuul.host.socket-timeout-millis=60000
#zuul.host.connect-timeout-millis=60000
@SpringBootApplication
//ribbon
@EnableDiscoveryClient
//feign
@EnableFeignClients
//Hystrix
@EnableHystrix
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
/**
* 将RestTemplate注入spring容器
* @return
*/
@Bean
@LoadBalanced //加入ribbon 的负载均衡器 ,轮询调用
RestTemplate restTemplate() {
return new RestTemplate();
}
}
@RestController
public class MemberApi {
@Autowired
private UserService userService;
/**
*
* springcloud中接口制件调用有两种方式
* 1.RestTemplate
* 2.fegin
*
*
* **/
@Autowired
private RestTemplate restTemplate;
@Autowired
private DiscoveryClient discoveryClient;
@RequestMapping(value="/addMember")
public String addMember(String name) {
//url = "http://localhost:8300/getUser"
//通过discoveryClient 获取服务信息列表
//List<ServiceInstance> services = discoveryClient.getInstances("zk-user");
/**
* restTemplate.getForObject("http://localhost:8300/getUser", String.class);
* restTemplate 以别名的方式访问需要添加
*
*
* **/
String s = restTemplate.getForObject("http://zk-user/getUser", String.class);
System.out.println(s);
return "添加会员";
}
/**
* feign客户单调用
* @return
*/
@RequestMapping(value="/getMember")
public String getMember() {
String s = userService.getUser();
return "会员调用用户服务-----"+s;
}
/**
* 开启Hystrix服务保护
* @return
*/
@RequestMapping(value="/memberHystrix")
@HystrixCommand(fallbackMethod = "memberHystrixFallBack")
public String memberHystrix() {
//默认线程池隔离,服务降级memberHystrixFallBack
//默认熔断10次请求
System.out.println(Thread.currentThread().getName());
String s = userService.getUser();
return "会员调用用户服务-----"+s;
}
public String memberHystrixFallBack() {
return "当前网络繁忙";
}
}
@Component
public class MemberServiceFallBack implements UserService{
/**
* Hystrix 统一返回
*/
public String getUser() {
return "用户忙";
}
}
/**
* Hystrix 统一返回 不用以下
* @HystrixCommand(fallbackMethod = "memberHystrixFallBack")
* @author Administrator
*
*/
@FeignClient(name = "zk-user",fallback = MemberServiceFallBack.class)
public interface UserService {
/**
* 调用user服务中getUser
* @return
*/
@GetMapping(value = "/getUser")
String getUser();
}
zk-user
/**
* Hystrix 统一返回 不用以下
* @HystrixCommand(fallbackMethod = "memberHystrixFallBack")
* @author Administrator
*
*/
@FeignClient(name = "zk-user",fallback = MemberServiceFallBack.class)
public interface UserService {
/**
* 调用user服务中getUser
* @return
*/
@GetMapping(value = "/getUser")
String getUser();
}
spring.application.name=zk-user
server.port=9100
#只能是本地才能这么写,如果连接远程需要加bootstrap.yml,zookeeper创建的是临时节点,服务关掉后节点也会被删除
#spring.cloud.zookeeper.connect-string=localhost:2181
spring:
cloud:
zookeeper:
discovery:
instancePort: ${server.port} #端口号
#instanceHost: yellowcong.com #当前服务的初始化地址(可以不填)
enabled: true
register: true
connectString: 192.168.233.100:2181 # 多节点配置,通过逗号分割192.168.253.31:2181,192.168.253.32:2181
@SpringBootApplication
/**
* 使用zookeeper 或使用connsoul时@EnableDiscoveryClient注册到注册中心
* @author Administrator
*
*/
@EnableDiscoveryClient
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
@RestController
public class UserApi {
@RequestMapping("/getUser")
public String getUser() {
/*
* try { Thread.currentThread().sleep(3000); } catch (InterruptedException e) {
* e.printStackTrace(); }
*/
return "获取用户";
}
}