首页 文章 精选 留言 我的

精选列表

搜索[分区技术],共10000篇文章
优秀的个人博客,低调大师

内网穿透技术浅评

科普一下给有需要的童鞋参考。穿透原理大致分如下几类: 1、代理穿透 原理示意图: 优势: 保持100%穿透成功率 用户无需公网IP 不足: 运营方提供公网访问入口,硬件投入大 带宽要求高,免费用户往往会被限速,产生免费使用上的“鸡肋” 2、直接穿透 原理示意图: 优势: 自主可控,无需第三方转发 保持100%穿透成功率 不足: 服务端必须具备公网IP 带宽取决于服务端和客户端两者的最小带宽(面向云主机带宽不友好,主要是贵!死贵!!) 由于直接暴露在公网,会有安全问题 需要自己搭建,门槛较高 3、P2P穿透 原理示意图: 优势: 点对点,能最大化使用带宽,使用感知友好 不足: Ipv4环境下成功率取决于NAT类型,移动网络(3G/4G下)基本没戏 Ipv6环境下成功率高,取决于防火墙策略(防火墙穿透) 几乎全基于UDP协议或其衍生自定义协议,安全性和可靠性或多或少存在缺陷 4、Ssh隧道穿透: 略 常用免费工具穿透姿势: -/- 代理穿透 直接穿透 P2P穿透 自主代理 公网IP 备注 花生壳 YES NO NO NO 不需要 限速到怀疑人生 teamviewer YES NO NO NO 不需要 烦人的商用提示 Ngrok YES YES NO YES 需要 Frp YES YES YES/UDP YES 需要 三种方式选其一 smarGate YES YES YES/TCP YES 不需要 同时支持,P2P优先 附:Frp:https://github.com/fatedier/frpNgrok:https://github.com/inconshreveable/ngroksmarGate: https://github.com/lazy-luo/smarGate

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

Cassandra技术介绍之开篇

Cassandra是一款分布式的去中心化的数据库,她脱胎于Dynamo以及bigtable,吸收了二者的架构以及数据模型在开源社区的孵化下达到今天这么一个程度。CAP理论中她更强调AP两点,当然C的属性也是可调的,C 和A 这2块在Cassandra身上可以看到一个权衡的存在。本文会从以下几个方面去介绍Cassandra相关知识: 基本架构 部署运维 使用方法 一:基本架构 Cassandra可以有多dc的部署方案,且也有适合在云环境下的部署方案,从复杂的snitch到simple的snitch。不同的环境有不同的部署方式,如果你希望你的cluster下面都是在一个dc,可以使用simple snitch,如果想要有更复杂的rack 以及dc方案,配合network的拓扑,可以组合成比较合适的一套多dc的架构。当然也有适合云上很亲和性的sn

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

Hystrix降级技术解析-Fallback

一、降级 所谓降级,就是指在在Hystrix执行非核心链路功能失败的情况下,我们如何处理,比如我们返回默认值等。如果我们要回退或者降级处理,代码上需要实现HystrixCommand.getFallback()方法或者是HystrixObservableCommand. HystrixObservableCommand()。 publicclassCommandHelloFailureextendsHystrixCommand<String>{ privatefinalStringname; publicCommandHelloFailure(Stringname){ super(HystrixCommandGroupKey.Factory.asKey("ExampleGroup")); this.name=name; } @Override protectedStringrun(){ thrownewRuntimeException("thiscommandalwaysfails"); } @Override protectedStringgetFallback(){ return"HelloFailure"+name+"!"; } } 二、Hystrix的降级回退方式 Hystrix一共有如下几种降级回退模式: 1、Fail Fast 快速失败 @Override protectedStringrun(){ if(throwException){ thrownewRuntimeException("failurefromCommandThatFailsFast"); }else{ return"success"; } } 如果我们实现的是HystrixObservableCommand.java则 重写 resumeWithFallback方法 @Override protectedObservable<String>resumeWithFallback(){ if(throwException){ returnObservable.error(newThrowable("failurefromCommandThatFailsFast")); }else{ returnObservable.just("success"); } } 2、Fail Silent 无声失败 返回null,空Map,空List fail silent.png @Override protectedStringgetFallback(){ returnnull; } @Override protectedList<String>getFallback(){ returnCollections.emptyList(); } @Override protectedObservable<String>resumeWithFallback(){ returnObservable.empty(); } 3、Fallback: Static 返回默认值 回退的时候返回静态嵌入代码中的默认值,这样就不会导致功能以Fail Silent的方式被清楚,也就是用户看不到任何功能了。而是按照一个默认的方式显示。 @Override protectedBooleangetFallback(){ returntrue; } @Override protectedObservable<Boolean>resumeWithFallback(){ returnObservable.just(true); } 4、Fallback: Stubbed 自己组装一个值返回 当我们执行返回的结果是一个包含多个字段的对象时,则会以Stubbed 的方式回退。Stubbed 值我们建议在实例化Command的时候就设置好一个值。以countryCodeFromGeoLookup为例,countryCodeFromGeoLookup的值,是在我们调用的时候就注册进来初始化好的。CommandWithStubbedFallback command = new CommandWithStubbedFallback(1234, "china");主要代码如下: publicclassCommandWithStubbedFallbackextendsHystrixCommand<UserAccount>{ protectedCommandWithStubbedFallback(intcustomerId,StringcountryCodeFromGeoLookup){ super(HystrixCommandGroupKey.Factory.asKey("ExampleGroup")); this.customerId=customerId; this.countryCodeFromGeoLookup=countryCodeFromGeoLookup; } @Override protectedUserAccountgetFallback(){ /** *Returnstubbedfallbackwithsomestaticdefaults,placeholders, *andaninjectedvalue'countryCodeFromGeoLookup'thatwe'lluse *insteadofwhatwewouldhaveretrievedfromtheremoteservice. */ returnnewUserAccount(customerId,"UnknownName", countryCodeFromGeoLookup,true,true,false); } 5、Fallback: Cache via Network 利用远程缓存 通过远程缓存的方式。在失败的情况下再发起一次remote请求,不过这次请求的是一个缓存比如redis。由于是又发起一起远程调用,所以会重新封装一次Command,这个时候要注意,执行fallback的线程一定要跟主线程区分开,也就是重新命名一个ThreadPoolKey。 Cache via Network.png publicclassCommandWithFallbackViaNetworkextendsHystrixCommand<String>{ privatefinalintid; protectedCommandWithFallbackViaNetwork(intid){ super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("RemoteServiceX")) .andCommandKey(HystrixCommandKey.Factory.asKey("GetValueCommand"))); this.id=id; } @Override protectedStringrun(){ //RemoteServiceXClient.getValue(id); thrownewRuntimeException("forcefailureforexample"); } @Override protectedStringgetFallback(){ returnnewFallbackViaNetwork(id).execute(); } privatestaticclassFallbackViaNetworkextendsHystrixCommand<String>{ privatefinalintid; publicFallbackViaNetwork(intid){ super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("RemoteServiceX")) .andCommandKey(HystrixCommandKey.Factory.asKey("GetValueFallbackCommand")) //useadifferentthreadpoolforthefallbackcommand //sosaturatingtheRemoteServiceXpoolwon'tprevent //fallbacksfromexecuting .andThreadPoolKey(HystrixThreadPoolKey.Factory.asKey("RemoteServiceXFallback"))); this.id=id; } @Override protectedStringrun(){ MemCacheClient.getValue(id); } @Override protectedStringgetFallback(){ //thefallbackalsofailed //sothisfallback-of-a-fallbackwill //failsilentlyandreturnnull returnnull; } } } 6、Primary + Secondary with Fallback 主次方式回退(主要和次要) 这个有点类似我们日常开发中需要上线一个新功能,但为了防止新功能上线失败可以回退到老的代码,我们会做一个开关比如使用zookeeper做一个配置开关,可以动态切换到老代码功能。那么Hystrix它是使用通过一个配置来在两个command中进行切换。 Primary + Secondary with Fallback.png /** *Sample{@linkHystrixCommand}patternusingasemaphore-isolatedcommand *thatconditionallyinvokesthread-isolatedcommands. */ publicclassCommandFacadeWithPrimarySecondaryextendsHystrixCommand<String>{ privatefinalstaticDynamicBooleanPropertyusePrimary=DynamicPropertyFactory.getInstance().getBooleanProperty("primarySecondary.usePrimary",true); privatefinalintid; publicCommandFacadeWithPrimarySecondary(intid){ super(Setter .withGroupKey(HystrixCommandGroupKey.Factory.asKey("SystemX")) .andCommandKey(HystrixCommandKey.Factory.asKey("PrimarySecondaryCommand")) .andCommandPropertiesDefaults( //wewanttodefaulttosemaphore-isolationsincethiswraps //2otherscommandsthatarealreadythreadisolated //采用信号量的隔离方式 HystrixCommandProperties.Setter() .withExecutionIsolationStrategy(ExecutionIsolationStrategy.SEMAPHORE))); this.id=id; } //通过DynamicPropertyFactory来路由到不同的command @Override protectedStringrun(){ if(usePrimary.get()){ returnnewPrimaryCommand(id).execute(); }else{ returnnewSecondaryCommand(id).execute(); } } @Override protectedStringgetFallback(){ return"static-fallback-"+id; } @Override protectedStringgetCacheKey(){ returnString.valueOf(id); } privatestaticclassPrimaryCommandextendsHystrixCommand<String>{ privatefinalintid; privatePrimaryCommand(intid){ super(Setter .withGroupKey(HystrixCommandGroupKey.Factory.asKey("SystemX")) .andCommandKey(HystrixCommandKey.Factory.asKey("PrimaryCommand")) .andThreadPoolKey(HystrixThreadPoolKey.Factory.asKey("PrimaryCommand")) .andCommandPropertiesDefaults( //wedefaulttoa600mstimeoutforprimary HystrixCommandProperties.Setter().withExecutionTimeoutInMilliseconds(600))); this.id=id; } @Override protectedStringrun(){ //performexpensive'primary'servicecall return"responseFromPrimary-"+id; } } privatestaticclassSecondaryCommandextendsHystrixCommand<String>{ privatefinalintid; privateSecondaryCommand(intid){ super(Setter .withGroupKey(HystrixCommandGroupKey.Factory.asKey("SystemX")) .andCommandKey(HystrixCommandKey.Factory.asKey("SecondaryCommand")) .andThreadPoolKey(HystrixThreadPoolKey.Factory.asKey("SecondaryCommand")) .andCommandPropertiesDefaults( //wedefaulttoa100mstimeoutforsecondary HystrixCommandProperties.Setter().withExecutionTimeoutInMilliseconds(100))); this.id=id; } @Override protectedStringrun(){ //performfast'secondary'servicecall return"responseFromSecondary-"+id; } } publicstaticclassUnitTest{ @Test publicvoidtestPrimary(){ HystrixRequestContextcontext=HystrixRequestContext.initializeContext(); try{ //将属性"primarySecondary.usePrimary"设置为true,则走PrimaryCommand;设置为false,则走SecondaryCommand ConfigurationManager.getConfigInstance().setProperty("primarySecondary.usePrimary",true); assertEquals("responseFromPrimary-20",newCommandFacadeWithPrimarySecondary(20).execute()); }finally{ context.shutdown(); ConfigurationManager.getConfigInstance().clear(); } } @Test publicvoidtestSecondary(){ HystrixRequestContextcontext=HystrixRequestContext.initializeContext(); try{ //将属性"primarySecondary.usePrimary"设置为true,则走PrimaryCommand;设置为false,则走SecondaryCommand ConfigurationManager.getConfigInstance().setProperty("primarySecondary.usePrimary",false); assertEquals("responseFromSecondary-20",newCommandFacadeWithPrimarySecondary(20).execute()); }finally{ context.shutdown(); ConfigurationManager.getConfigInstance().clear(); } } } } 三、总结 降级的处理方式,返回默认值,返回缓存里面的值(包括远程缓存比如redis和本地缓存比如jvmcache)。 但回退的处理方式也有不适合的场景: 1、写操作 2、批处理 3、计算 以上几种情况如果失败,则程序就要将错误返回给调用者。 参考资料:https://github.com/Netflix/Hystrix/wiki

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

iOS ShareSDK桥接技术

前言 在游戏开发中,难免会出现与原生平台有交互才能完成一些特定的必要的功能。比如iOS的内购功能,或者你想用一款第三方SDK,但是此SDK却没有对应平台的版本、并且未提供插件的情况下,就会涉及到与第三方平台的交互。 Unity3D 简介:Unity3D(以下简称U3D)是由Unity Technologies开发的一个让玩家轻松创建诸如三维视频游戏、建筑可视化、实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。 Unity3D调用原生iOS接口 Unity3D 无法直接调用iOS原生的OC或者swift语言,但是Unity3D使用的C#可以和C进行交互。而C是可以和OC进行交互的。从而就可以实现C#调用OC。 以ShareSDK的Unity桥接为例: 先定义 分享的C语言方法 void __iosShareSDKShare (int reqID, int platType, void *content, void *observer){ NSMutableDictionary *shareParams = __getShareParamsWithString(contentStr); [ShareSDK share:platType parameters:shareParams onStateChanged:nil]; } C#中则可以像下面代码一样进行引入和调用: using System.Runtime.InteropServices; [DllImport("__Internal")] private static extern void __iosShareSDKShare (int reqID, int platType, string content, string observer); 其中DllImport为一个Attribute,目的是通过非托管方式将库中的方法导出到C#中进行使用。而传入"__Internal"则是表示这个是一个静态库或者是一个内部方法。通过上面的声明,这个方法就可以在C#里面进行调用了 比如Unity游戏需要分享的时候直接调用下面方法就可以了: void ShareContent (int reqID, PlatformType platform, ShareContent content) { __iosShareSDKShare (reqID, (int)platform, content.GetShareParamsStr(), _callbackObjectName); } iOS 调用Unity的接口 在特定场景下也会有iOS接口调用Unity的C#接口的情况,比如分享后回调的分享结果就要传递到原生的unity层。最简单的方式是通过UnitySendMessage方法来调用Unity所定义的方法。 仍然以ShareSDK的回调为例: 在Unity的里ShareSDK.cs定义一个回调方法 private void _Callback (string data) { Debug.LogFormat ("result string = {0}", data); } 挂载ShareSDK.cs到Main Camera中 在OC层,在ShareSDK的分享回调block执行UnitySendMessage void __iosShareSDKShare (int reqID, int platType, void *content, void *observer) { NSMutableDictionary *shareParams = __getShareParamsWithString(contentStr); [ShareSDK share:platType parameters:shareParams onStateChanged:^(SSDKResponseState state, NSDictionary *userData, SSDKContentEntity *contentEntity, NSError *error) { NSString *resultStr = nil; // process resultStr // ... UnitySendMessage(observer, "_Callback", [resultStr UTF8String]); }]; } 其中 observer值为挂载的"Main Camera" 注意:UnitySendMessage方式无法同步获取返回值,并且必须要挂载到对象后才能调用,复杂需求可以使用 非托管的方式进行交互,具体可以参考:https://www.jianshu.com/p/1ab65bee6692 Cocos2d 是一个基于MIT协议的开源框架,用于构建游戏、应用程序和其他图形界面交互应用。可以让你在创建自己的多平台游戏时节省很多的时间。 由于主流的cocos2d游戏开发语言是C++,而C++ 和OC是可以直接交互的,只需把OC的实现文件.m修改为.mm即可,那么只需要定义一个C++的接口直接调用OC既可 typedef void(*C2DXShareResultEvent) (int reqID, C2DXResponseState state, C2DXPlatType platType, C2DXDictionary *res); void C2DXiOSShareSDK::shareContent(int reqID,C2DXPlatType platType, C2DXDictionary *content,bool useClientShare, C2DXShareResultEvent callback) { NSMutableDictionary *parameters = convertPublishContent(content); [ShareSDK share:(SSDKPlatformType)platType parameters:parameters onStateChanged:^(SSDKResponseState state, NSDictionary *userData, SSDKContentEntity *contentEntity, NSError *error) { // process callback ... //callback callback(reqID,(C2DXResponseState)state,(C2DXPlatType)platType,userInfoDict); }]; }

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

Docker技术实践——高级篇

1.1 搭建私有仓库 我们需要看下如何搭建容器的私有仓库: Mavan的管理一样,Dockers不仅提供了一个中央仓库,同时也允许我们使用registry搭建本地私有仓库。 私有仓库有许多优点: 1.节省网络带宽,不用每个人都去中央仓库上面去下载,只需要从私有仓库中下载即可; 2.提供镜像资源利用,针对于公司内部使用的镜像,推送到本地的私有仓库中,以供公司内部相关人员使用。 #docker pull registry #dockerrun -d -p 5000:5000 --name registry-srv registry 默认仓库存放于容器内的/tmp/registry目录下 镜像需要通过docker tag进行修改,符合仓库需要。 #docker push 192.168.1.104:5000/hello-world 如果出现如下错误: http: server gave HTTP response to HTTPS client 这是因为docker registry交互默认使用的是https,然而此处搭建的私有仓库只提供http服务,所以当与私有仓库交互时就会报上面的错误。 MAC机器中修改: 在Docker的preference中,点击Daemon,Basic页签中,在Insecureregistries中增加一行: http://192.168.1.104:5000 点击apply and restart重启docker即可。 Ubuntu机器中修改: (Ubuntu的地址为/etc/init/docker.conf),在其中增加 --insecure-registry 192.168.1.104:5000 exec"$DOCKERD"$DOCKER_OPTS--raw-logs --insecure-registry 192.168.1.104:5000 然后重启 docker; #service docker restart; 如果上述方法不行,那么如下: 在”/etc/docker/“目录下,创建”daemon.json“文件。在文件中写入: { "insecure-registries":["192.168.1.104:5000"]} 然后重启 docker; #service docker restart; 1.2 上传镜像 # docker push registry:5000/image_name 1.3 查看镜像 # curl -XGET http://registry:5000/v2/_catalog # curl -XGEThttp://registry:5000/v2/image_name/tags/list 例如: #curl -XGEThttp://192.168.1.104:5000/v2/_catalog 输出如下: {"repositories":["centos","hello-world"]} # curl -XGEThttp://192.168.1.104:5000/v2/centos/tags/list 输出如下: {"name":"centos","tags":["7.1"]} 1.4 Docker-compose Docker-compose需要docker-compose.yml文件,依赖yml文件,没有yml文件就没有勇武之地了。 Docker Compose是一个用来定义和运行复杂应用的Docker工具。使用Compose,你可以在一个文件中定义一个多容器应用,然后使用一条命令来启动你的应用,完成一切准备工作。 编辑docker-compose.yml内容如下: mysql: image: csphere/mysql:5.5 ports: - "3306:3306" wordpress: image: csphere/wordpress:10 ports: -"80:80" 启动容器如下: docker-composeup-d 关闭容器: docker-compose stop 2. Q&A 2.1 编译错误 Rpmdb checksum is invalid: dCDPT(pkgchecksums): elfutils-libs.x86_64 0:0.168-8.el7 - u 答:在 Docker 文件中第一个 yum 之前加入如下命令对rpmdb 进行构筑. RUN rpm --rebuilddb&& \

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

Docker技术实践——中级篇

1.1 存储机制 每个镜像由多个镜像层组成,镜像层都是只读的,从下往上,以栈方式组合在一起,组成容器的根文件系统。镜像文件默认保存在主机的/var/lib/docker/volumes中。 容器层是可读写层。每个容器运行时都有自己的容器层,保存容器运行相关的数据,容器层之下的所有镜像都是只读的,多个容器可以共享一个镜像。容器层是保存在/var/lib/docker/containers路径。每次新建容器时,只需要为每个容器新建一个可写的数据层,而不用复制所有的镜像层。 容器层和镜像层都保存在宿主机的文件系统中,通过Docker存储驱动来管理。 1.2 数据卷和存储驱动 容器使用数据卷保证数据持久性,删除容器时候,所有不在数据卷中的数据都会被删除。因为数据卷是主机上的一个文件或者目录,不受存储驱动程序管理。 Docker设计了一套存储驱动插件框架,开发者可以基于此套标准,设计开发自己的存储驱动。 可以使用docker info查看当前存储驱动。 使用哪种存储驱动取决于用户在宿主机上使用何种文件系统。有些存储驱动可以工作在不同的后端文件系统上。 可以在启动Docker使用使用--storage-driver来指定。 Docker中每种存储驱动都是基于Linux文件系统或卷管理工具的。 1.3 定制Docker Daemon 因为Docker Daemon有七八十个启动选项,根据应用场景定制Docker运行环境就显得非常有必要。 在命令行中输入dockerd即可启动,就是默认的方式启动Daemon了。 如果开启debug模式,可以执行 #dockerd -D 仓库相关配置: --disable-legacy-registry选项,可以选择不从旧版本的镜像仓库中下载镜像。因为Docker从1.6版本后,支持从V2版本的镜像仓库下载镜像。 使用镜像仓库,使用参数—registry-mirror选项。 此外,还有何网络配置相关的等等。 因为,旧版本docker的配置文件默认的在 /etc/default/docker ,现在已不推荐。 变量的使用查看/lib/systemd/system/docker.service 可以参考官方指南:

资源下载

更多资源
腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Rocky Linux

Rocky Linux

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

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册