接口分类
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 "获取用户"; } }