首页 文章 精选 留言 我的

精选列表

搜索[学习],共10000篇文章
优秀的个人博客,低调大师

spring cloud 学习(6) - zuul 微服务网关

微服务架构体系中,通常一个业务系统会有很多的微服务,比如:OrderService、ProductService、UserService...,为了让调用更简单,一般会在这些服务前端再封装一层,类似下面这样: 前面这一层俗称为“网关层”,其存在意义在于,将"1对N"问题 转换成了"1对1”问题,同时在请求到达真正的微服务之前,可以做一些预处理,比如:来源合法性检测,权限校验,反爬虫之类... 传统方式下,最土的办法,网关层可以人肉封装,类似以下示例代码: LoginResult login(...){ //TODO 预处理... return userService.login();//调用用户服务的登录方法 } Product queryProduct(...){ //TODO 预处理... return productService.queryProduct();//调用产品服务的查询方法 } Order submitOrder(...){ //TODO 预处理... return orderService.submitOrder();//调用订单服务的查询方法 } 这样做,当然能跑起来,但是维护量大,以后各个微服务增加了新方法,都需要在网关层手动增加相应的方法封装,而spring cloud 中的zuul很好的解决了这一问题,示意图如下: Zuul做为网关层,自身也是一个微服务,跟其它服务Service-1,Service-2, ... Service-N一样,都注册在eureka server上,可以相互发现,zuul能感知到哪些服务在线,同时通过配置路由规则(后面会给出示例),可以将请求自动转发到指定的后端微服务上,对于一些公用的预处理(比如:权限认证,token合法性校验,灰度验证时部分流量引导之类),可以放在所谓的过滤器(ZuulFilter)里处理,这样后端服务以后新增了服务,zuul层几乎不用修改。 使用步骤: 一、添加zuul依赖的jar包 compile 'org.springframework.cloud:spring-cloud-starter-zuul' 二、application.yml里配置路由 zuul: routes: api-a: path: /api-user/** service-id: service-provider sensitive-headers: api-b: path: /api-order/** service-id: service-consumer 解释一下:上面这段配置表示,/api-user/开头的url请求,将转发到service-provider这个微服务上,/api-order/开头的url请求,将转发到service-consumer这个微服务上。 三、熔断处理 如果网关后面的微服务挂了,zuul还允许定义一个fallback类,用于熔断处理,参考下面的代码: package com.cnblogs.yjmyzz.spring.cloud.study.gateway; import org.springframework.cloud.netflix.zuul.filters.route.ZuulFallbackProvider; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.client.ClientHttpResponse; import org.springframework.stereotype.Component; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.nio.charset.Charset; /** * Created by yangjunming on 2017/7/14. */ @Component public class ServiceConsumerFallbackProvider implements ZuulFallbackProvider { @Override public String getRoute() { return "service-consumer"; } @Override public ClientHttpResponse fallbackResponse() { return new ClientHttpResponse() { @Override public HttpStatus getStatusCode() throws IOException { return HttpStatus.OK; } @Override public int getRawStatusCode() throws IOException { return this.getStatusCode().value(); } @Override public String getStatusText() throws IOException { return this.getStatusCode().getReasonPhrase(); } @Override public void close() { } @Override public InputStream getBody() throws IOException { return new ByteArrayInputStream("Service-Consumer不可用".getBytes()); } @Override public HttpHeaders getHeaders() { HttpHeaders headers = new HttpHeaders(); MediaType mt = new MediaType("application", "json", Charset.forName("UTF-8")); headers.setContentType(mt); return headers; } }; } } 开发人员只要在getRoute这个方法里指定要处理的微服务实例,然后重写fallbackResponse即可。 此时,如果观察/health端点,也可以看到hystrix处于融断开启状态 四、ZuulFilter过滤器 过滤器是一个很有用的机制,下面分几种经典场景演示下: 4.1、token校验/安全认证 网关直接暴露在公网上时,终端要调用某个服务,通常会把登录后的token传过来,网关层对token进行有效性验证,如果token无效(或没传token),提示重新登录或直接拒绝。另外,网关后面的微服务,如果设置了spring security中的basic Auth(即:不允许匿名访问,必须提供用户名、密码),也可以在Filter中处理。参考下面的代码: package com.cnblogs.yjmyzz.spring.cloud.study.gateway; import com.netflix.zuul.ZuulFilter; import com.netflix.zuul.context.RequestContext; import org.apache.commons.codec.binary.Base64; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants; import org.springframework.stereotype.Component; import javax.servlet.http.HttpServletRequest; /** * Created by yangjunming on 2017/7/13. */ @Component public class AccessFilter extends ZuulFilter { private static Logger logger = LoggerFactory.getLogger(AccessFilter.class); @Override public String filterType() { return FilterConstants.PRE_TYPE; } @Override public int filterOrder() { return 0; } @Override public boolean shouldFilter() { return true; } @Override public Object run() { RequestContext ctx = RequestContext.getCurrentContext(); HttpServletRequest request = ctx.getRequest(); Object token = request.getParameter("token"); //校验token if (token == null) { logger.info("token为空,禁止访问!"); ctx.setSendZuulResponse(false); ctx.setResponseStatusCode(401); return null; } else { //TODO 根据token获取相应的登录信息,进行校验(略) } //添加Basic Auth认证信息 ctx.addZuulRequestHeader("Authorization", "Basic " + getBase64Credentials("app01", "*****")); return null; } private String getBase64Credentials(String username, String password) { String plainCreds = username + ":" + password; byte[] plainCredsBytes = plainCreds.getBytes(); byte[] base64CredsBytes = Base64.encodeBase64(plainCredsBytes); return new String(base64CredsBytes); } } Filter一共有4种类型,其常量值在org.springframework.cloud.netflix.zuul.filters.support.FilterConstants 中定义 // Zuul Filter TYPE constants ----------------------------------- /** * {@link ZuulFilter#filterType()} error type. */ String ERROR_TYPE = "error"; /** * {@link ZuulFilter#filterType()} post type. */ String POST_TYPE = "post"; /** * {@link ZuulFilter#filterType()} pre type. */ String PRE_TYPE = "pre"; /** * {@link ZuulFilter#filterType()} route type. */ String ROUTE_TYPE = "route"; 安全校验,一般放在请求真正处理之前,所以上面的示例filterType指定为pre,剩下的只要在shouldFilter()、run()方法中重写自己的逻辑即可。 4.2 动态修改请求参数 zuulFilter可以拦截所有请求参数,并对其进行修改,比如:终端发过来的数据,出于安全要求,可能是经过加密处理的,需要在网关层进行参数解密,再传递到后面的服务;再比如:用户传过来的token值,需要转换成userId/userName这些信息,再传递到背后的微服务。参考下面的run方法: public Object run() { try { RequestContext context = getCurrentContext(); InputStream in = (InputStream) context.get("requestEntity"); if (in == null) { in = context.getRequest().getInputStream(); } String body = StreamUtils.copyToString(in, Charset.forName("UTF-8")); body = "动态增加一段内容到body中: " + body; byte[] bytes = body.getBytes("UTF-8"); context.setRequest(new HttpServletRequestWrapper(getCurrentContext().getRequest()) { @Override public ServletInputStream getInputStream() throws IOException { return new ServletInputStreamWrapper(bytes); } @Override public int getContentLength() { return bytes.length; } @Override public long getContentLengthLong() { return bytes.length; } }); } catch (IOException e) { rethrowRuntimeException(e); } return null; } 更多filter的示例,可以参考官网:https://github.com/spring-cloud-samples/sample-zuul-filters 4.3 灰度发布(Gated Launch/Gray Release) 大型分布式系统中,灰度发布是保证线上系统安全生产的重要手段,一般的做法为:从集群中指定一台(或某几台)机器,每次做新版本发布前,先只发布这些机器上,先观察一下是否正常,如果稳定运行后,再发布到其它机器。这种策略(相当于按部分节点来灰度),大多数情况下可以满足要求,但是有一些特定场景,可能不太适用。 比如:笔者所在的“美味不用等”公司,主要B端用户为各餐饮品牌的商家,多数情况下,如果新上了一个功能,希望找一些规模较小的餐厅做试点,先看看上线后的运行情况,如果运行良好,再推广到其它商家。 再比如:后端服务有N多个版本在同时运行,比如V1、V2,现在新加了一个V3版本(这在手机app应用中很常见),希望只有部分升级了app的用户访问最新的V3版本服务,其它用户仍然访问旧版本,待系统稳定后,再大规模提示用户升级。 对于这些看上去需求各异的灰度需求,

优秀的个人博客,低调大师

自然语言理解-从规则到深度学习

1. 引言 自然语言理解是人工智能的核心难题之一,也是目前智能语音交互和人机对话的核心难题。维基百科有如下描述[1]: Natural language understanding (NLU) is a subtopic of natural language processing in artificial intelligence that deals with machine reading comprehension. NLU is considered an AI-hard problem. 对于AI-hard的解释如下: In the field of artificial intelligence, the most difficult problems are informally known as AI-complete

优秀的个人博客,低调大师

《Scala机器学习》一一3.2 理解Spark的架构

3.2 理解Spark的架构并行化是将工作负载划分为在不同线程或不同节点上执行的子任务。下面介绍Spark实现并行化的原理,以及它如何管理子任务的执行和子任务之间的通信。3.2.1 任务调度Spark工作负载的划分由弹性分布式数据集(Resilient Distributed Dataset,RDD)的分区数决定,这是Spark的基本抽象和管道结构。RDD是一种可并行操作的、不可变元素的分区集合。具体细节可能取决于Spark的运行模式,图3-2为Spark任务/资源调度的示意图。 图3-2 通用的Spark任务调度示意图。尽管在图中没有明确标识,Spark Context通常会在端口4040上打开一个HTTP UI(并发情形将打开4041、4042等),在任务执行期间会一直这样。Spark Master UI的端口通常是8080(虽

优秀的个人博客,低调大师

安全理论:学习如何应对网络恐怖活动

【51CTO.com快译】关于网络恐怖活动的消息近期层出不穷。全世界正在遭遇不同程度的网络恐怖主义,包括真正的恐怖活动、黑客入侵、勒索软件等等。在这篇文章中,我们将讨论如何应对网络恐怖主义,包括你可以采取的安全措施,确保你不会最终成为受害者。我们会与你详细探讨上网时的深入思考、在意每次点击以及网络恐怖活动的类型和防御方法。 深入思考我们要做事情首先要思考,无论你是一个孩子还是一个四十岁的父母,你都可以进入网络恐怖主义的世界。恐怖分子在网上招募他们的原因很多。首先,它更安全,而且不会冒被警察抓住的风险;此外,人们在网上交谈更容易,在互联网上使用不同的视频和图像来操纵他们的想法更容易,而这些在现实世界中发挥作用的机会却很小。 这就是恐怖分子为什么要网上招聘的原因。因此,你应该做的第一件事就是正确地思考。你仍然会在网上交友,但要确保你在现实生活中也能认识他们。不要仅仅因为你认为他们说的是真的而和某人交朋友。当你被问及某事或提供信息时,要慎重提供信息,以保证你的安全。 在意每一次点击上个月全球互联网发生了大规模的赎金袭击事件。黑客入侵了不同的公司、医院和个人电脑系统,他们希望通过比特币付费,以确保不会伤害你的电脑。一些受到袭击的人向黑客付了钱。经过几天的袭击,白帽子的人想出了一个系统来摆脱黑客企图,遏制他们对无辜网民的勒索行为。尽管如此,全球网民依旧处在不安的情绪中。如何确保你的安全,根据数据重要程度,可以这样来处理。 首先,确保你的数据每天都受到保护,时常备份你的文件。随着云存储系统的普及,无论是Dropbox还是谷歌驱动器,将所有数据转移到云存储都不难。 如果你的系统上有重要数据,建议你在不同的系统进行备份。当你管理网站时,同样的规则也适用。不要依赖主机平台来创建你的网站备份,你应该创建定期备份以确保不遭受黑客攻击。 下一步,要了解在哪里点击安全,在哪里点击不安全。你在网站上采取任何行动之前,一定要看一个你被重定向的网站的域名。不要下载来源不明的文件。谷歌浏览器推出了一款名为"安全/非安全符号"的新功能。如果你查看你的浏览器的URL部分,你会发现URL的初始部分有一个选项,它可以告诉你这个站点是否安全,可以发送非常重要的信息。它通常被称为SSL证书。有些网站是值得信任的,但还没有他们的SSL证书。在未来几年内,这将清楚地表明哪些是可以信任的。 网络恐怖主义攻击的类型在这里,我们将讨论一些常见的网络恐怖主义攻击,这些将帮助你确定你是否做出错误的决定。 第一个通常被称为简单的非结构化攻击。在这种情况下,恐怖分子使用大众制造的简单系统和工具。他们经常使用钓鱼之类的方法进入别人的系统。另外,歌曲和视频下载网站往往带有恶意软件。 下一个类型被称为高级结构化攻击。在这种情况下,黑客在攻击你之前做他们的研究。这种攻击来自网络级别,在几乎所有的情况下,黑客控制网络或IP,因此,网络中的所有内容。 还有一种称为复杂协调器的类型。这是最大的类型,个人不太可能受到这种类型的恐怖主义的影响。在这种情况下,黑客建立他们的团队去大规模攻击某个国家或组织。最后,一定要确保你知道你在互联网上做什么。不要让任何人在你的无知中冒险! 作者:刘妮娜 来源:51CTO

资源下载

更多资源
优质分享App

优质分享App

近一个月的开发和优化,本站点的第一个app全新上线。该app采用极致压缩,本体才4.36MB。系统里面做了大量数据访问、缓存优化。方便用户在手机上查看文章。后续会推出HarmonyOS的适配版本。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

用户登录
用户注册