微服务从设计到部署(一)微服务简介 - oopsguy - 博客园

mikel阅读(1103)

来源: 微服务从设计到部署(一)微服务简介 – oopsguy – 博客园

链接https://github.com/oopsguy/microservices-from-design-to-deployment-chinese
译者Oopsguy

目前微服务受到很多关注:文章、博客、社交媒体上的讨论和会议演讲。他们正在迅速走向加德纳技术成熟度曲线(Gartner Hype cycle)的高峰。与此同时,也有持怀疑态度的软件社区人员认为微服务没什么新鲜可言。反对者声称它的思想只是面向服务架构(SOA)的重塑。然而,无论是炒作还是怀疑,不可否认微服务架构模式具有非常明显的优势——特别是在实施敏捷开发和复杂的企业应用交付方面。

本章节是七章之中介绍关于的设计、构建和部署微服务方面的内容。您将了解微服务的由来和与传统单体应用模式的比较。这本电子书描述了许多关于微服务架构方面的内容。无论是对您的项目的意义,或者是如何去应用它,您都将了解到微服务架构模式的优点和缺点。

我们先来看看为什么要考虑使用微服务。

1.1、构建单体应用

我们想一下,您开始制作一个新的打车应用,打算与 Uber 和 Hailo 竞争。经过初步交流与需求收集,您将手动或者使用类似 Rails、Spring Boot、Play或者Maven等平台来生成一个新项目。

这个新应用是一个模块化的六边形架构,如图 1-1 所示:

图 1-1、一个简单的打车应用

应用程序的核心是由模块实现的业务逻辑,它定义了服务、领域对象和事件。围绕核心的是与外部世界接口对接的适配器。适配器示例包括了数据库访问组件、生产和消费消息的消息组件和 web 组件,它们暴露了 API 或者实现了一个 UI。

尽管有一个逻辑模块化的架构,但应用程序被作为一个整体进行打包和部署。实际格式取决于应用程序的语言和框架。例如,许多 Java 应用程序被打包成 WAR 文件并部署在如 Tomcat 或者 Jetty 之类的应用服务器上。其他 Java 应用程序是打包成自包含(self-contained)的可执行 JAR。类似地,Rails 和 Node.js 应用程序被打包为目录层次结构。

以这种风格编写的应用是很常见的。他们很容易开发,因为我们的 IDE 和其他工具专注于构建单个应用程序。这些应用程序也很容易测试。您可以通过简单地启动并使用如 Selenium 测试包来测试 UI 以轻松地实现端到端(end-to-end)测试。单体应用同样易于部署。你只需拷贝打包好的应用程序到服务器。您还可以通过运行多个副本和结合负载均衡器来扩展应用。在项目的早期阶段,它运作良好。

1.2、走向单体地狱

不幸的是,这种简单的方法有很大的局限性。成功的应用有一个趋势,随着时间推移而变得越来越臃肿。在每个冲刺时期,您的开发团队实现了更多的用户需求,这意味着添加了许多行代码。几年之后,您的小而简单的应用将会逐渐成长为庞然大物似的单体。为了给出一个极端的示例,我最近和一位开发者做了交谈,他正在编写一个工具用于从他们的数百万行代码(lines of code,LOC)应用中分析数千个 JAR 之间的依赖。我相信这是大量开发者在多年齐心协力下创造了这样的野兽。

一旦您的应用程序成为了一个庞大、复杂的单体,您的开发组织可能陷入了一个令人痛苦的世界。敏捷开发和交付的任何一次尝试都将原地徘徊。一个主要问题是应用程序实在是非常复杂。对于任何一个开发人员来说,这是在太大了,这是可以理解的。最终,正确地修复 bug 和实现新功能变得非常困难且耗时。此外,这个趋势就像是往下的螺旋。如果基本代码难以理解,那么改变将不会变得正确。您最终得到的是一个巨大且不可思议的大泥球

应用程序的规模也将减缓发展。应用程序越大,启动的时间越长。我调查过开发者们的单体应用的大小和性能,一些报告的启动时间为 12 分钟。我也听说过应用程序启动需要 40 分钟以上的怪事。如果开发人员经常要重启应用服务器,那么很大一部分时间都是在等待中度过,他们的生产力将受到限制。

另一个大问题是,复杂的单体应用本身就是持续部署的障碍。如今,SaaS 应用发展到了每天可将变更推送到生产中多次。这对于复杂的单体非常困难,因为您必须重新部署整个应用程序才能更新其中任何一部分。这对我之前提到的漫长的启动时间也不会有什么帮助。此外,因为变化的影响通常不是很清楚,您很可能需要做大量的手工测试。因此,持续部署是不可能做到的。

当不同模块存在资源需求冲突时,单体应用也可能难以扩展。例如,一个模块可能会执行 CPU 密集型图像处理逻辑,理想情况下是部署在 Amazon EC2 Compute Optimized 实例中。另一个模块可能是内存数据库,最适合 EC2 Memory-optimized 实例。然而,因为这些模块被部署在一起,您必须在硬件选择上做出妥协。

单体应用的另一个问题是可靠性。因为所有模块运行在同一进程。任何模块的一个 bug,比如内存泄漏,可能会拖垮整个进程。此外,由于应用程序的所有的实例都是相同的,该错误将影响到整个应用的可用性。

最后但并非是最不重要的,单体应用使得采用新的框架和语言变得非常困难。例如,我们假设您有 200 万行代码使用了 XYZ 框架编写。使用较新的 ABC 框架来重写整个应用,这将是非常昂贵的(在时间和成本方面),即使那个框架非常好。因此,这对于采用新技术是一个非常大的障碍。您在项目开始时无论选择何种新技术都将会感到困扰。

总结一下:您有一个成功的关键业务应用程序,它已经发展成为一个只有少数开发人员(如果有的话)能够理解的巨大单体。它使用了过时、非生产性技术编写的,这使得招聘优秀开发人员变得困难。应用程序难以扩展,不可靠。因此敏捷开发和应用交付是不可能的。

那么您能做些什么呢?

1.3、微服务-解决复杂问题

许多组织,如 Amazon、eBay 和 Netflix,已经采用现在所谓的微服务架构模式解决了这个问题,而不是构建一个臃肿的单体应用。它的思路是将您的应用程序分解成一套较小的互连服务。

一个服务通常实现了一组不同的特性或者功能,例如订单管理、客户管理等。每一个微服务都是一个迷你应用,它自己的六边形架构包括业务逻辑以及多个适配器。

一些微服务会暴露一个供其他微服务或应用客户端消费的 API。其他微服务可能实现了一个 web UI。在运行时,每个实例通常是一个云虚拟机(virtual machine,VM)或者一个 Docker 容器。

例如,前面描述的系统可能分解成如图 1-2 所示:

图 1-2、一个单体应用分解成微服务

应用程序的每个功能区域现在都由自己的微服务实现。此外,Web 应用程序被分为一组更简单的 Web 应用程序。例如,以我们的出粗车为例,一个专门是乘客的,一个专门是司机的。这使得它更容易地为特定的用户、司机、设备或者专门的用例部署不同的场景。每个后端服务暴露一个 REST API,大部分的服务消费由其他服务提供的 API。例如,司机管理使用了通知服务器来告知一个可用司机关于一个潜在路程。UI 服务调用了其他服务来渲染页面。服务也可以使用异步、基于消息的通信。本电子书后面将会详细介绍服务间的通信。

一些 REST API 也暴露给移动端应用供司机和乘客使用。然而,应用不能直接访问后端服务。相反,他们之间的通信是由一个称为 API 网关(API Cateway)的中介负责。API 网关负责负载均衡、缓存、访问控制、API计量和监控,可以通过使用 NGINX 来实现。第 2 章详细讨论 API 网关。

图 1-3、开发和交付中的缩放立方(Scale Cube)

微服务架构模式相当于此缩放立方的 Y 轴坐标,此立方是一个来自《架构即未来》的三维伸缩模型。另外两个坐标轴是由运行多个相同应用程序副本的负载均衡器组成的 X 轴缩放和 Z 轴坐标(或者数据分区),其中请求的属性(例如,一行记录的主键或者客户标识)用于将请求路由到特定的服务器。

应用程序通常将这三种类型的坐标方式一起使用。Y 轴坐标将应用分解成微服务,如图 1-2 所示。

在运行时,X 坐标轴上运行着服务的多个实例,每一个服务配合负载均衡器以满足吞吐量和可用性。某些应用程序也有可能使用 Z 坐标轴来进行分区服务。图 1-4 展示了如何用 Docker 将旅途管理(Trip Management)服务部署到 Amazon EC2 上运行。

图 1-4、使用 Docker 部署旅途管理服务

在运行时,旅途管理服务由多个服务实例组成,每个服务实例是一个 Docker 容器。为了实现高可用,容器是在多个云虚拟机上运行的。服务实例的前方是一个如 NGINX 的负载均衡器,用于跨实例分发请求。负载均衡器也可以处理其他问题,如缓存访问控制API 度量监控

微服务架构模式明显影响到了应用程序与数据库之间的关系。与与其他共享单个数据库模式(schema)服务不同,每一个服务都有自己的数据库模式。一方面,这种做法是与企业级数据库数据模型的想法不符,此外,它经常导致一些数据冗余。然而,如果您想从微服务中受益,每一个服务都应该有自己的数据库模式。因为它做到了松耦合。图 1-5 展示了数据库架构示例应用程序。

每个服务都有自己的数据库。而且,服务可以使用一种最适合其需求、号称多语言持久架构(polyglot persistence architecture)的数据库。例如,司机管理,找到与潜在乘客接近的司机必须使用支持高效地理查询的数据库。

图 1-5、打车应用的数据库架构

从表面上看,微服务架构模式类似于 SOA。微服务是由一组服务组成。然而,换另一种方式去思考微服务架构模式,它是没有商业化的 SOA,没有集成 Web 服务规范(WS-*)和企业服务总线(Enterprise Service Bus,ESB)。基于微服务的应用支持更简单、轻量级的协议,例如,REST,而不是 WS-*。他们也尽量避免使用 ESB,而是实现微服务本身具有类似 ESB 的功能。微服务架构也拒绝了 SOA 的其他部分,例如,数据访问规范模式概念。

1.4、微服务的优点

微服务架构模式有许多非常好的地方。第一,它解决了复杂问题。它把可能会变得庞大的单体应用程序分解成一套服务。虽然功能数量不变,但是应用程序已经被分解成可管理的块或者服务。每个服务都有一个以远程过程调用(RPC)驱动或者消息驱动的 API 明确定义的边界。微服务架构模式强制一定程度的模块化,实际上,使用单体基础代码来实现是极其困难的。因此,个体服务能被更快地开发,并更容易理解与维护。

第二,这种架构使得每个服务都可以由一个团队独立专注开发。开发者可以自由选择任何符合服务 API 契约的技术。当然,更多的组织是希望通过技术选型限制来避免完全混乱的状态。然而,这种自由意味着开发人员不再有可能在这种自由的新项目开始时使用过时的技术。当编写一个新服务时,他们可以选择当前的技术。此外,由于服务比较小,使用当前技术重写旧服务将变得更加可行。

第三,微服务架构模式可以实现每一个微服务独立部署。开发人员根本不需要去协调部署本地变更到它们的服务。这些变更一经测试即可立即部署。比如,UI 团队可以执行 A|B 测试,并快速迭代 UI 变更。微服务架构模式使得持续部署成为可能。

最后,微服务架构模式使得每个服务能够独立扩展。您可以仅部署满足每个服务的容量和可用性约束的实例数目。此外,您可以使用与服务资源要求最匹配的硬件。例如,您可以在 EC2 Compute Optimized 实例上部署一个 CPU 密集型图像处理服务,并且在 EC2 Memory-optimized 实例上部署一个内存数据库服务。

1.5、微服务的缺点

就像 Fred Brooks 近 30 年前写的《人月神话》说的,没有银弹。像其他技术一样,微服务架构模式也是如此,存在着缺点。其中一个缺点就是名称本身。微服务这个术语的重点过多偏向于服务的规模。事实上,有些开发者主张构建极细粒度的 10-100 LOC(代码行) 服务虽然小型服务可能比较好,但重要的是要记住,小型服务只是一种手段,而不是主要目标。微服务的目标在于充分分解应用程序以方便应用敏捷开发和部署。

微服务另一个主要的缺点是由于微服务是一个分布式系统而变得复杂。开发者需要选择和实现基于消息或者 RPC 的进程间通信机制。此外,由于目标请求可能很慢或者不可用,他们还必须编写代码来处理部分故障。虽然这些都不是很复杂高深的事,但模块间通过语言级方法/过程调用相互调用,这比单体应用要复杂得多。

微服务的另一个挑战是分区数据库架构。更多多个业务实体的业务事务是相当普遍的。这些事务在单体应用中的实现显得微不足道,因为只有一个单独的数据库。在基于微服务的应用程序中,您需要更新不同服务所有用的数据库。通常不会选择分布式事务,不仅仅是因为 CAP 定理。他们根本不支持如今高度可扩展的 NoSQL 数据库和消息代理。您最后不得不使用最终基于一致性的方法,这对于开发人员来说更具挑战性。

测试微服务应用程序也很复杂。例如,使用现代的框架如 Sprig Boot,只需要编写一个测试类来启动一个单体 web 应用程序并测试其 REST API。相比之下,一个类似的测试类对于微服务来说需要启动该服务及其所依赖的任何服务,或者至少为这些服务配置存根。再次声明,虽然这不是一件高深的事情,但不要低估了这样做的复杂性。

微服务架构模式的另一个主要的挑战是实现了跨越多服务变更。例如,我们假设您正在实现一个变更服务 A、B 和 C 的需求,其中 A 依赖于 B,并且 B 依赖于 C。在单体应用程序中,您可以简单地修改相应的模块、整合变更并一次性部署他们。相反,在微服务中您需要仔细规划和协调出现的变更到每一个服务。例如,您需要更新服务 C,然后更新服务 B,最后更新服务 A。幸运的是,大多数变更只会影响一个服务;需要协调的多服务变更相对较少。

部署基于微服务的应用程序也是非常地复杂。一个单体应用可以很容易地部署到基于传统负载均衡器的一组相同的服务器上。每个应用程序实例都配置有基础设施服务的位置(主机和端口),比如数据库和消息代理。相比之下,微服务应用程序通常由大量的服务组成。例如,据 Adrian Cockcroft,Hailo 拥有 160 个不同的服务,Netflix 拥有超过 600 个服务。

每个服务都有多个运行时实例。还有更多的移动部件需要配置、部署、扩展和监控。此外,您还需要实现服务发现机制,使得服务能够发现需要与之通信的任何其他服务的位置(主机和端口)。传统比较麻烦的基于票据(ticket-based)和手动操作方式无法扩展到如此复杂程度。因此,成功部署微服务应用程序要求开发人员能高度控制部署方式和高度自动化。

一种自动化的方式是使用现成的平台即服务(PaaS),如 Cloud Foundry。PaaS 为开发人员提供了一种简单的方式来部署和管理他们的微服务。它让开发人员避开了诸如采购和配置 IT 资源等烦恼。同时,配置 PaaS 的系统与网络专业人员可以确保最佳实践和落实公司策略。

自动化微服务部署的另一个方式是开发自己的 PaaS。一个普遍的起点是使用集群方案,如 Kubernetes,与 Docker 等容器技术相结合。在本书最后我们将看到基于软件的应用交付方式如 NGINX 是如何在微服务级别处理缓存、访问控制、API 计量和监控,可以帮助解决这个问题。

1.6、总结

构建复杂的微服务应用程序本质上是困难的。单体架构模式只适用于简单、轻量级的应用程序,如果您使用它来构建复杂应用,您最终会陷入一个痛苦的世界。微服务架构模式是复杂、持续发展应用的一个更好的选择。尽管它存在着缺点和实现挑战。

在后面的章节中,我将介绍微服务架构的方方面面并探讨诸如服务发现、服务部署方案以及将单体应用重构为服务的策略。

微服务实战:NGINX Plus 作为反向代理服务器

By Floyd Smith

10000 个网站中有超过 50% 使用 NGINX,这主要是因为它具有作为反向代理服务器的能力。您可以 NGINX 放在当前应用程序前面甚至是数据库服务器以获取各种功能 —— 更高的性能、更高的安全性、可扩展性、灵活性等。你现有的应用程序只需要配置代码和作出很少或无需改变。对于存在性能压力的站点,或者预计未来存在高负荷,效果看起来似乎没那么神奇。

那么这与微服务有什么关系呢?实现一个反向代理服务器,并使用 NGINX 的其他功能来为您提供架构灵活性。反向代理服务器、静态和应用文件缓存、SSL/TLS 和 HTTP/2 都会从您的应用程序剔除。让应用程序只做它该做的事,NGINX 还可作为负载均衡器,微服务实施过程中的一个关键角色。先进的 NGINX Plus 的功能包含了复杂的负载均衡算法、多种方式的会话持久和管理监控,这些对微服务尤其有用(NGINX 最近还增加了使用 DNS SRV 记录的服务发现支持,这是一个顶尖的功能)。而且,如本章所述,NGINX 可以自动化部署微服务。

此外,NGINX 还提供了必要的功能来支撑 NGINX 微服务参考架构中的三大模型。代理模型使用 NGINX 作为 API 网关;网格路由模型使用了一个额外的 NGINX 作为进程间通信中枢;Fabric 模型中每个微服务使用一个 NGINX 来控制 HTTP 流量,在微服务之间实现 SSL/TLS,这非常具有突破性。

这 11 款 Chrome 扩展,让网页看起来更舒服 - 少数派

mikel阅读(1249)

来源: 这 11 款 Chrome 扩展,让网页看起来更舒服 – 少数派

Chrome 已经成为越来越多人的默认浏览器。其丰富多样的扩展程序可以大幅度提高网页浏览体验。这篇文章,为你推荐几款让网页浏览更加舒适的扩展程序。

为什么你们就不能加个空格呢?

这款扩展专门治疗由于汉字与英文之间没有空格导致的腰酸,背痛以及神情恍惚。其内置的空格之神,可以为一切中文字和半形的英文、数字、符号之间插入空白。

相关文章:为什么你们就是不能加个空格呢?

下载:为什么你们就不能加个空格呢?(Chrome 网上应用店)

维基百科视觉现代化:Wikiwand

多年来,维基百科网页的视觉风格坚定不移地停留在 Web2.0 时代。Wikiwand 可以让你看到一个属于这个时代的维基百科。

除了视觉上的提升,Wikiwand 也添加了一些人性化的交互:比如超链接悬浮窗,类似 Kindle 的书签功能,搜索联想,黑色模式等等…

相关文章:轻、快、美,浏览维基百科的魔杖:Wikiwand

下载:Wikiwand(Chrome 网上应用店)

微博界面改造:眼不见心不烦

或许你也像我一样,面对微博右侧的「主播红人榜」全是陌生面孔,怀疑自己一定是老了。为了麻痹自己,我开始使用「眼不见心不烦」。这款扩展不仅可以屏蔽主播红人榜,亚洲新歌榜,会员专区等一切右边栏;还可以无限制地屏蔽关键词、用户、来源…

下载:眼不见心不烦(Chrome 网上应用店)

Safari 的阅读体验:阅读模式

「阅读模式」这款扩展可以为 Chrome 带来了类似 Safari 的阅读体验。点击图标即可进入,再次点击退出,完全的无痛体验。有一种 Chrome 原生阅读模式的错觉。

下载:阅读模式(Chrome 网上应用店)

悬浮大图:Imagus

嫌弃「查看大图」永远不够大?有了 Imagus 这款扩展程序,只要鼠标在图片上悬浮三秒,图片就会以原始尺寸显示出来。

下载:Imagus(Chrome 网上应用店)

关灯看视频

视频页面关灯是一个老生常谈的问题了,许多网站并没有支持这个功能,如果你有这个需要,这款「关灯看视频」可以提供比较广泛的支持。亲测兼容优酷,Youtube,腾讯视频以及 Freestyle。

下载:关灯看视频

Darkness

连 iOS11 都开始以「智能反转颜色」变相支持夜间模式了,众网页支持夜间模式还只是个美好愿景。

Darkness 可以为 Google,Facebook,YouTube,Reddit 等不存在的网站提供完美的夜间模式支持,不会有图片反转,文字颜色奇怪等尴尬问题。当然了,Darkness适配的网站还很少,如果你需要广泛适用的,可能需要下面这款神级扩展。

下载:Darkness(Chrome 网上应用店)

Stylish

许多网页的视觉风格是用 CSS 文件进行管理的,替换网页本身的 CSS 可以达到美化的目的了。通过安装 CSS,可以把知乎「拍扁」,让微博网页版变得简洁无比,让 Feedly 用上 Material Design 等等等…… Stylish 作为一个 CSS 管理器,可以让替换 CSS 变得简单。

至于前文提到的「暴力夜间模式」以及更多好用的 CSS,可以阅读这篇文章详细了解:不喜欢某个网站的样子?用 Stylish 给它一键「换肤」

下载:Stylish(Chrome 网上应用店)

油猴脚本:Tampermonkey

在介绍这款扩展之前,我们来了解一下「用户脚本」的用处:用户脚本可以通过修改网页为特定网站增加功能,美化等等。Tampermonkey 类似 Stylish,是一个用户脚本管理器,由于用户脚本比 CSS 更为神通广大,其应用面比 Stylish 更广。有了这个管理器,就可以轻松的安装和管理脚本了。先安装 Tampermonkey,再去寻找和安装脚本即可。(此时你的 Chrome 会有一种扩展里套扩展的感觉)

关联阅读:用 Chrome 的人都需要知道的「神器」扩展:「油猴」使用详解

下载:Tampermonkey(Chrome 网上应用店)

这里为大家推荐两个用户脚本分享网站,相当于脚本商店:

OpenUserJS

Greasyfork.org

除了以上两个网站,GitHub 上也可以找到用户脚本。为了展示用户脚本的能力,这里推荐几个:

Yet Another Weibo Filter

可以实现前文中「眼不见心不烦」的功效,几乎无异。

下载:Yet Another Weibo Filter(Greasy Fork)

视频站启用 HTML5 播放器

用 HTML5 播放器替代优酷土豆、腾讯、新浪、微博、搜狐、乐视等视频网站的 Flash 播放器,免受 MacBook 风扇声音洗礼。

下载:视频站启用 HTML5 播放器(Greasy Fork)

跳过网站等待、验证码及登录

移除登录,下载,验证码等无法跳过的倒计时。

下载:跳过网站等待、验证码及登录(Greasy Fork)

克制

对于扩展与脚本的使用,这里有句忠告:在接下来的探索过程中,你可能会发现油猴脚本更加强大额功能,但冲突与混沌一定不是你想要的效果,在添加和使用的过程中,建议谨慎添加,勤于管理。

WIN7 下SQL Server 2008 提示“无法进行远程调试问题”的个人解决方法_一跃一_新浪博客

mikel阅读(1217)

WIN7 下SQL Server 2008 提示“无法进行远程调试问题”的个人解决方法_一跃一_新浪博客,一跃一,

来源: WIN7 下SQL Server 2008 提示“无法进行远程调试问题”的个人解决方法_一跃一_新浪博客

一、在“控制面板”中,单击“系统和安全”。

二、单击“Windows 防火墙”。

三、为 TCP 135 添加例外,这是 DCOM 用来与远程计算机通信的端口:

  1. 在“Windows 防火墙”控制面板中,单击“高级设置”。
  2. 如果“用户帐户控制”对话框出现,请单击“是”继续。
  3. “高级安全 Windows 防火墙”窗口将打开。
  4. 单击“入站规则”。
  5. 在“操作”窗格中,单击“新建规则”。
  6. 此时将显示“新建入站规则向导”。
  7. 在“要创建的规则类型”下选择“端口”,然后单击“下一步”。
  8. 选择“TCP”和“特定本地端口”,然后在“特定本地端口”框中输入“135”。
  9. 单击“下一步”。
  10. 在“操作”页上选择“允许连接”,然后单击“下一步”。
  11. 在“配置文件”页上,选择要在其中应用规则的配置文件。 通常,您需要选择“域”,并且可能选择“专用”,但不会选择“公用”。
  12. 单击“下一步”。
  13. 在“名称”页上的名称框中键入一个有意义的名称,取名叫“SQL 135”规则。。
  14. 单击“完成”。

四、如果您的域策略要求通过 IPSec 进行网络通信,则执行此步骤。 否则,请转到步骤 5:

  1. 单击“新建规则”。

    此时将显示“新建入站规则向导”。

  2. 在“要创建的规则类型”下选择“端口”,然后单击“下一步”。
  3. 选择“UDP”和“特定本地端口”,然后在“特定本地端口”框中输入“4500”和“500”。
  4. 单击“下一步”。
  5. 在“操作”页上选择“允许连接”,然后单击“下一步”。
  6. 在“配置文件”页上,选择您在步骤 3 中选择的相同的配置文件。
  7. 单击“下一步”。
  8. 在“名称”页上的名称框中键入一个名称,取名叫“SQL 4500,500”规则。
  9. 单击“完成”。
  10. 将关闭“高级安全 Windows 防火墙”窗口。

五、再将“SQL Server Management Studio”程序图标对应的“Ssms.exe”文件也添加进入站规则里就可以了。

WIN7 <wbr>下SQL <wbr>Server <wbr>2008 <wbr>提示“无法进行远程调试问题”的个人解决方法

最新iOS发布App Store详细图文教程 - CocoaChina_让移动开发更简单

mikel阅读(1162)

CocoaChina前身是全球成立最早规模最大的苹果开发中文站,现致力为所有移动开发者提供资讯服务、问答服务、代码下载、工具库及人才招聘服务

来源: 最新iOS发布App Store详细图文教程 – CocoaChina_让移动开发更简单

c58adf586a0a12cc0de55c8b255f5342.png

网上有很多关于iOS发布上架的教程,但大多比较旧而且不完整、不够清晰。所以整理了一个详细完整的iOS APP发布上架App Store的图文教程。分享给小白到大神路上前进的你我。

上架iOS需要一个苹果开发者账号,还没有的话申请一个。

上架过程分七个步骤,按步骤一步步来。照着教程做简单、快速就能完成iOS APP的上传。

  • 1、创建APP身份证(App IDs)
  • 2、申请iOS发布证书
  • 3、申请iOS发布描述文件
  • 4、导入iOS证书到xocde打包IPA
  • 5、在iTunes Connect创建App
  • 6、上传IPA到App Store
  • 7、上传好IPA回到iTunes Connect填写APP信息并提交审核

一、创建唯一标示符App IDs

APP IDs在后面创建发布文件,创建APP时都要用到。

如果之前iOS调试时创建过了,就不用重新创建了,还是用那个appid。

首先打开开发者中心https://developer.apple.com/cn/,进入证书页面。

1.1点击证书、ID及配件文件,进入设置。

1.1.png

 

1.2选择App IDs –>点击+创建一个新的App ID

 

1.2.png

其中有两项需要你自己填:

  • 第一项Name,用来描述你的App ID,这个随便填,没有什么限制,最好是项目名称,这样方便自己辨识(不允许中文)
  • 第二项Bundle ID (App ID Suffix),这是你App ID的后缀,需要仔细填写。用来标示我们的 app,使它有一个固定的身份,和你的程序直接相关。填写  Explicit App ID 的格式为:com.company.appName,照着格式写,写个方便记的,后面很多地方要用到。
  • 第三项App Services,默认会选择2项,不能修改,其它如APP需要推送通知就勾选下推送通知的服务,没有其他要求选择默认的,然后点击Continue确认,下一步。

1.3.png

检查下没有错的话直接点击Register后点击Done完成App ID的创建。

1.4.png

二、申请发布证书

这里使用Appuploader工具,直接申请导出p12证书文件和.mobileprovision描述文件

2.1打开Appuploader,输入苹果开发者中心账号,登录。

2.1.png

2.2选择Certification

2.2.png

2.3点击+ADD,这里有开发证书等等创建选项,这里选第三项发布证书。

如果你之前有了发布证书也可以不用创建,用之前的也行,苹果规定个人只能创建3个发布证书。

2.3.png

2.4输入,证书名称(随意) 邮箱(任何邮箱都行) 密码(后面打包编译时用到)然后点击ok

2.4.png

2.5此时生成了好了一个发布证书,点击p12 File,下载证书文件,保存到电脑。

2.5.png

这样就得到了一个p12的iOS发布证书文件

三、申请发布描述文件

3.1回到软件点击Profiles

3.1.png

3.2点击+ADD,这里有开发描述文件等等选项,这里选发布描述文件。

3.2.png

3.3选择APP IDs,之前在开发者中心创建的,这里会自动出现。

3.3.png

3.4勾选刚创建的发布证书关联好,输入name,点击ok

注意:如果你之前创建了多个发布证书,下面发布证书框显示多个发布证书,

可以全选,默认最新创建的发布证书,打包时输入最新创建的发布证书密码。

ps:发布证书不同的app可以通用的,描述文件不同就行了。

3.4.png

3.5此时生成了发布描述文件,点击 Download下载到电脑保存

3.5.png

四、Xcode上传证书编译打包

1、导入iOS证书p12到钥匙串

1.1打开钥匙串助手,双击p12文件,默认钥匙串是(登录),注意这里一定要选择(系统)

这样后面打包时iOS证书才不会报错,输入创建iOS证书设置的密码,导入进去。

1.png

1.2.png

1.2导入后提示此证书是由未知颁发机构签名的,因为不是用本机的钥匙串文件申请的iOS证书

不过没关系,设置一下信任就好了

2.png

1.3双击证书、点击信任,使用此证书时,设置为始终信任。

3.png

3.1.png

2、xcode配置iOS证书和打包环境

2.1用xocde打开你的项目,点击进入设置证书界面。

有两个地方都要设置

选择Code Signing下面的release(发布版)Debugs是测试版,上架App Store选择发布版的。

然后选择你刚上传的对应iOS发布证书

4.1.png4.png

2.2回到基本信息设置界面,Bundie 这项填写,最先创建的那个appid,跟创建iOS描述文件时选择的要一样。

现在下面还有个错误提示,因为还没有导入iOS描述文件。

5.png

2.3双击.mobileprovision描述文件,闪一下就自动导入到xcode,不报错表示可以了。

6.png

2.4选择xcode菜单栏如果图所示

7.png

2.5把Archived修改为Release

8.png

2.6点击选择设备,选择为打包设备。

9.png

3、项目打包IPA包导出

3.1选择菜单栏如图所示,如果Archive还是灰色的,说明之前的配置没有生效,退出重新打开下。

点击Archive,开始打包。

10.png

3.2打包进度条走完后,会弹出以下界面,点击Expcrt

11.png

3.3这里是个人开发账户发布到App Store,所以选择第一个,点击Next。

12.png

3.4选择你的开发者账号,还没登录会提示你登录,点击Choose,会检查你的证书是否正确。

13.png

3.5iOS证书检测通过就到了这一步、点击Export,就会导出 一个文件夹,里面就是IPA文件,大功告成了。

14.png

14.1.png

这个IPA包就可以上传到App Store了。

五、在iTunes Connect创建App

5.1进入iTunes Connect进入创建APP,选择我的APP点击左上角+号选择新建APP,输入你的应用名称,语言,套装ID,之前在开发者中心创建的对应APP IDs(与刚才创建iOS发布描述文件时所选的appid要一致,这样用iOS证书打包的IPA,上传就能对应识别到)sku不能写中文,点击创建。

5.2.png

5.3这里提示要用到Xcode或者Application loader提交IPA,等下可以用Appuploader直接上传ipa,更快。

现在APP各项信息都没填写,等下把IPA上传成功了再填写。

这里构建版本旁边还没有出现+号,后面上传了IPA就会出现,等下会用到。

5.3.png

六、Windows环境下上传IPA到App Store

6.1打开Appuploader程序,点击Upload.

6.1.png

6.2选择刚生成的iap包、Appuploader将自动上传你的IPA,当出现以下提示时,说明上传成功,点击deail可以查看APP信息。

6.3.png

七、回到iTunes Connect提交审核

7.1上传好了IPA,然后回到iTunes Connect,进入填写信息的页面,下边有一个构建版本的选项,之前这旁边没有+号的,如果上传成功了,过几分钟旁边会出现一个加号按钮,点击一下+然后会出现你刚上传的APP,有上传多个版本会出现多个,点选、点击完成即可。

注意:如果一段时间后没有出现+号,可能ipa不符合要求,会有个反馈邮件过来,根据反馈的问题修改后重新上传。

7.1.png

添加了构建版本,如果要修改添加,打包时增加下版本号,如果跟之前的相同那上传不了。

点击删除又会出现+号,可选择其他上传的版本去提交审核。

7.02.png

7.03.png

7.2然后设置好APP相关的信息、类别,价格、销售服务等。

7.20.png

7.21.png

截图的话、如果你的应用只支持 iPhone,你只需提供 5.5 英寸的显示屏截图

像素-纵向:1242 x 2208,横向:2208 x 1242

72 dpi、RGB、平展、不透明
高品质 JPEG 或 PNG 图像文件格式)即可。

其他尺寸的勾选引用5.5寸的就行,最多上传5张。

如果你的应用支持iPad,一套 12.9 英寸的屏幕截图就可以满足要求。

APP图标的规格则为1024*1024

7.3设置好相应的APP信息后,点击提交以供审核。

7.3.png

7.4提交审核回到我的APP查看会提示正在等待审核,审核有时很快一两天,或要几天时间,常登陆看看审核情况,或看邮件提示。

如果变成可供销售,恭喜你~上架成功了,如果显示被拒绝,点击查看问题,根据反馈修改再重新上传。

7.4.png

angularjs弹出框方法二 - sinat_36146776的博客 - CSDN博客

mikel阅读(1035)

来源: angularjs弹出框方法二 – sinat_36146776的博客 – CSDN博客


使用时,首先引入这三个必要的文件


注意,在主模块依赖注入
var routerApp=angular.module('routerApp',['ui.router','ngAnimate','tm.pagination','ui.bootstrap']);
routerApp.controller('takeGoodsSearch',['$scope','$http','$modal','$anchorScroll','$log','$location','$rootScope',function($scope,$http,$modal,$anchorScroll,$log,$location,$rootScope) {
$scope.cancelApply=function(index){
$scope.result={};
$scope.result.title = "提示消息";
$scope.result.msg = "确定要删除?";
$rootScope.loanId=index;
$modal.open({
templateUrl : 'tpls/common/reconfirmMessage.html',
controller :ModalInstanceCtrl,
resolve : {
requestResults : function() {
return $scope.result;
}
}
});
}
var ModalInstanceCtrl = function($scope, $modalInstance,requestResults) {
$scope.results = requestResults;
// 确认按钮(close()可以带参数)
$scope.ok = function() {
$modalInstance.close();
$http.post('/deletePickup',$rootScope.loanId).success(function(){
reSearch();
});
};
// 取消按钮
$scope.cancel = function() {
$modalInstance.dismiss('cancel');
};
};
//弹窗结束
}])

reconfirmMessage.html:

 

angularjs弹出框方法一 - sinat_36146776的博客 - CSDN博客

mikel阅读(1243)

触发事件:取消申请 × 模态框(Modal)标题 –> 确定 关闭

来源: angularjs弹出框方法一 – sinat_36146776的博客 – CSDN博客

触发事件:用id控制

  1. <button class=“btn-cancel” data-toggle=“modal” data-target=“#myModal”>取消申请</button>
  1. <!– 模态框(Modal) –>
  2. <div class=“modal fade” id=“myModal” tabindex=“-1” role=“dialog” aria-labelledby=“myModalLabel” aria-hidden=“true”>
  3.     <div class=“modal-dialog”>
  4.         <div class=“modal-content”>
  5.             <div class=“modal-header”>
  6.                 <!– 关闭按钮 –>
  7.                 <button type=“button” class=“close” data-dismiss=“modal” aria-hidden=“true”>
  8.                     ×
  9.                 </button>
  10.                 <!– 标题 –>
  11.                 <h3 class=“modal-title” data-ng-bind=‘results.title’></h3>
  12.                 <!– <h4 class=“modal-title” id=“myModalLabel”>
  13.                     模态框(Modal)标题
  14.                 </h4> —>
  15.             </div>
  16.             <div class=“modal-body”>
  17.                 <b data-ng-bind=‘results.message’></b>
  18.             </div>
  19.             <div class=“modal-footer”>
  20.                 <button type=“button” class=“btn btn-primary” data-ng-click=“ok()”>确定</button>
  21.                 <button type=“button” class=“btn btn-default” data-dismiss=“modal”>关闭</button>
  22.             </div>
  23.         </div><!– /.modal-content –>
  24.     </div><!– /.modal –>
  25. </div>

angular.js 下如何动态插入删除dom节点 一介布衣

mikel阅读(977)

angular.js ,插入dom,移除dom,angular.js 下如何动态插入删除dom节点,一介布衣

来源: angular.js 下如何动态插入删除dom节点 一介布衣

angular.js 是新一代web开发框架,它轻松在web前端实现了MVC模式,相比 JQuery 模式,这种新玩意竟然不需要开发者直接去操作dom .

作为前端开发而不去操作dom ,这简直是一个玩笑! 没错,确实是这样的.关于 angular.js 的详细说明及事例请在博客搜索 angular.js

既然上面提到 angular.js 下无需用户直接操作dom ,而是在编译间断 dom 与 控制层model 实现了双向绑定,一方做出改变,另一方就会立即改变,那问题来了,我想插入一个文本框和按钮,并且文本框里数据要和控制层一个属性绑定,按钮要实现 ng-click 事件,如何做?

传统实现方法,在父节点里直接新增一段 dom ,html标签的事件也会被自动注册.

angular.js实现方法: 将节点添加到父节点后,我们需要重新编译, 将数组对象 (包含 ng-click 等 angular.js 指令)绑定到当前作用域.绑定以后对应的angular.js 指令才会有效.

前提是:

插入dom节点以后,需要手动调用 $compile 服务(调用前先依赖注入) 才能将 angular.js 指令和模型绑定生效.类似如下代码:

$('div[name=father]').html(
  $compile('<input type="text" ng-model="person.name" /> <input type="input" ng-model="person.age" value="{{person.age}}" /><a ng-show="$index!=0" style="color:red;" ng-click="del($index)">移除</a>'
  )(scope)
);

很明显,没有 $compile 服务,无法将上面插入的dom绑定到当前作用域.但是这种拼串的方式看上去很挫,我们说过 angular.js 是用模型和控制器去实现双向绑定. 这一段不伦不类的 JQuery 代码实在有点鹤立鸡群的感觉.

下面简绍第二种方案.

ng-repeat

这是angular.js 的一个迭代指令,如果你之前接触过 ASP.NET 的话, repeat 控件一定很熟悉吧,他们功能相似,都是从一个集合里,遍历元素然后迭代出来展示在UI上.

你可能有个疑问, 用ng-repeat 迭代出来就能把 angular.js 的事件绑定到当前作用域吗?

是的.

因为 ng-repeat 在实现上就自动执行了 $compile 服务.

这样省事了不少,我们唯一需要关注的是模型.

比如我们用一个数组容器作为迭代数据集 ,比如 var list=[{id:100,age:30,name:”张三”}]

            <div ng-repeat="person in list">
                <input type="text" ng-model="person.name" /> <input type="input" ng-model="person.age" value="{{person.age}}" />
                <a ng-show="$index!=0" style="color:red;" ng-click="del($index)">移除</a>
            </div>
            <a ng-click="add()">增加一个</a>

控制器响应的需要实现 add() 方法 和 del(idx) 方法.

$scope.add=function(){
    var obj={id:101,age:30,name:"李四"};
    $scope.list.push(obj);
}

$scope.del=function(idx){
    $scope.list.splice(idx,1);
}

ok,这样我们就可以动态添加 /删除 dom 节点了.

angular.js删除一条记录后如何让视图自动更新 | Angular中文社区

mikel阅读(872)

Angular是Google开发的前端技术框架。

来源: angular.js删除一条记录后如何让视图自动更新 | Angular中文社区

假设我们有这么一个视图:

记录 操作
记录1 删除
记录2 删除

想实现的效果是:点击 记录1 后面的删除,如果删除成功,视图自动更新为

记录 操作
记录2 删除

视图的html代码如下

<table>
    <tr>
        <th>记录</th>
        <th>操作</th>
    </tr>
    <tr ng-repeat="record in records">
        <td>{ { record.title } }</td>
        <td><a href ng-click="delete(record)">删除</a></td>
    </tr>
</table>

要实现视图自动更新,可以在控制器代码里这样写

$scope.delete = function(record) {
    $scope.records.splice($scope.records.indexOf(record), 1);
};

Android studio 出现 Unsupported major.minor version 52.0 - yxhuang2008的专栏 - CSDN博客

mikel阅读(1496)

来源: Android studio 出现 Unsupported major.minor version 52.0 – yxhuang2008的专栏 – CSDN博客

最近更新了Android studio 之后,出现了Error:Java.lang.UnsupportedClassVersionError:com/android/dx/command/Main : Unsupported major.minor version 52.0 异常,

一、这是因为 compileSdKVersion 和 buildToosVersion 版本对不上导致的,例如我这里compileSdkVersion 是23,而 buildToolsVersion 却是 24.0.0.rc2 。所以,出现 Unsupported major.minor version 52.0 异常

只要将 complileSdkVersion 和 builToolsVersion 的版本修改一致就可以了。

例如,我这里将 buildToolsVersion 修改为 23.0.2 就可以了。

二、如果不是这个问题,可以进 Open Module Settings 看看 Complie Sdk Version 和 Build Tools Version 是否为空

三、如果都不是上面的这个问题,那就把jdk 的版本升级的 1.8