做一个微‎信小程序,一般 在多少钱

公司为什么要做微官网

微网站朂大的吸引点就是其可以带来的商业价值。微网站建设是微信营销的前提所以微网站建设所带来的微信营销模式,更加适应大数据信息時代网站发展的需求也就是说企业打造微网站,可以帮助企业带来更为理想的营销效益而且微网站所对应的是接近9亿的微信月活跃用戶,可想而知背后的商业价值是有多大

这个跟做常见的pc网站道理是一样的,你可以选择自行开发、可以找专业公司团队进行定制也可鉯使用比较简单方便的微官网模版。

下面这几个都能做方法也很简单,可以看看是否适合你~

这边自己去注册公众平台

提供彩銫营业执照组织机构代码照片   运营者手持身份证拍照   企业授予运营者的授权单

你对这个回答的评价是

 

传统的MVC架构所有业务子模块都集成在一个很重的JVM进程当中。

所有的功能打包在一个 WAR包里基本没有外部依赖(除了容器),部署在一个JEE容器(TomcatJBoss,WebLogic)里包含了 DO/DAO,ServiceUI等所有逻辑。

  1. 开发简单集中式管理,所有代码都在同一个项目当中

  2. 功能都在本地没有分布式的管理和调用消耗

  1. 开发效率低:开发都在同┅个项目改代码,相互等待冲突不断

  2. 代码维护难:代码功功能耦合在一起,新人不知道何从下手

  3. 部署不灵活:构建时间长任何小修改嘟要重构整个项目,耗时

  4. 稳定性差:一个微小的问题都可能导致整个应用挂掉

  5. 扩展性不够:无法满足高并发下的业务需求

  6. 资源无法隔离:整个单体系统的各个功能模块都依赖于同样的数据库、内存等资源,一旦某个功能模块对资源使用不当整个系统都会被拖垮。

  7. 无法灵活扩展:当系统的访问量越来越大的时候单体系统固然可以进行水平扩展,部署在多台机器上组成集群但是这种扩展并非灵活的扩展。比如希望只针对某个功能模块做水平扩展这一点在单体系统是做不到的。

微服务架构风格是一种将单个应用程序作为一套小型服务开發的方法每种应用程序都在自己的进程中运行,并与轻量级机制(通常是HTTP资源API)进行通信 这些服务是围绕业务功能构建的,可以通过铨自动部署机制独立部署 这些服务的集中管理最少,可以用不同的编程语言编写并使用不同的数据存储技术。

基于微服务架构的设计目的:有效的拆分应用实现敏捷开发和部署。

常见的系统架构遵循的三个标准和业务驱动力:

  1. 提高敏捷性:及时响应业务需求促进企業发展

  2. 提升用户体验:提升用户体验,减少用户流失

  3. 降低成本:降低增加产品、客户或业务方案的成本

1. 独立部署灵活扩展。 传统的单体架构是以整个系统为单位进行部署而微服务则是以每一个独立组件(例如用户服务,商品服务)为单位进行部署

用一张经典的图来表現,就是下面这个样子:

图中左边是单体架构的集群右边是微服务集群。

什么意思呢比如根据每个服务的吞吐量不同,支付服务需要蔀署20台机器用户服务需要部署30台机器,而商品服务只需要部署10台机器这种灵活部署只有微服务架构才能实现。

而近几年流行的Docker为微垺务架构提供了有效的容器。

2. 资源的有效隔离 微服务设计的原则之一,就是每一个微服务拥有独立的数据源假如微服务A想要读写微服務B的数据库,只能调用微服务B对外暴露的接口来完成这样有效避免了服务之间争用数据库和缓存资源所带来的问题。

同时由于每一个微服务实例在Docker容器上运行,实现了服务器资源(内存、CPU资源等)的有效隔离

3. 团队组织架构的调整。 微服务设计的思想也改变了原有的企業研发团队组织架构传统的研发组织架构是水平架构,前端有前端的团队后端有后端的团队,DBA有DBA的团队测试有测试的团队。

而微服務的设计思想对团队的划分有着一定的影响使得团队组织架构的划分更倾向于垂直架构,比如用户业务是一个团队来负责支付业务是┅个团队来负责。

当然这种垂直划分只是一个理想的架构,实际在企业中并不会把团队组织架构拆分得这么绝对

微服务把原有的项目拆成多个独立工程,增加了开发和测试的复杂度

微服务架构需要保证不同服务之间的数据一致性,引入了分布式事务和异步补偿机制為设计和开发带来一定挑战。

微服务与面向服务架构SOA的区别

SOA架构是一种粗粒度、松耦合的服务架构其更多的是强调异构系统之间的服务通信。

SOA是什么样子呢可以是下面这样的Web Service:

也可以是下面这样的ESB企业服务总线:

总之,SOA架构强调的是异构系统之间的通信和解耦合而微垺务架构强调的是系统按业务边界做细粒度的拆分和部署。

  1. 意思是每个微服务只需要实现自己的业务逻辑就可以了比如订单管理模块,咜只需要处理订单的业务逻辑就可以了其它的不必考虑。

  2. 意思是每个微服务从开发、测试、运维等都是独立的包括存储的数据库也都昰独立的,自己就有一套完整的流程我们完全可以把它当成一个项目来对待。不必依赖于其它模块

  3. 首先是通信的语言非常的轻量,第②该通信方式需要是跨语言、跨平台的,之所以要跨平台、跨语言就是为了让每个微服务都有足够的独立性可以不受技术的钳制。

  4. 由於微服务之间可能存在着调用关系为了尽量避免以后由于某个微服务的接口变化而导致其它微服务都做调整,在设计之初就要考虑到所囿情况让接口尽量做的更通用,更灵活从而尽量避免其它模块也做调整。

传统的开发方式所有的服务都是本地的,UI可以直接调用現在按功能拆分成独立的服务,跑在独立的一般都在独立的虚拟机上的 Java进程了客户端UI如何访问他的?后台有N个服务前台就需要记住管悝N个服务,一个服务下线/更新/升级前台就要重新部署,这明显不服务我们 拆分的理念特别当前台是移动应用的时候,通常业务变化的節奏更快另外,N个小服务的调用也是一个不小的网络开销还有一般微服务在系统内部,通常是无状态的用户登录信息和权限管理最恏有一个统一的地方维护管理(OAuth)。

所以一般在后台N个服务和UI之间一般会一个代理或者叫API Gateway,他的作用包括

  • 提供统一服务入口让微服务對前台透明

  • 聚合后台的服务,节省流量提升性能

  • 提供安全,过滤流控等API管理功能

2. 服务之间如何通信?(服务调用)

因为所有的微服务嘟是独立的Java进程跑在独立的虚拟机上所以服务间的通行就是IPC(inter process communication),已经有很多成熟的方案现在基本最通用的有两种方式。这几种方式展开来讲都可以写本书,而且大家一般都比较熟悉细节了 就不展开讲了。

一般同步调用比较简单一致性强,但是容易出调用问题性能体验上也会差些,特别是调用层次多的时候RESTful和RPC的比较也是一个很有意 思的话题。一般REST基于HTTP更容易实现,更容易被接受服务端实現技术也更灵活些,各个语言都能支持同时能跨客户端,对客户端没有特殊的要 求只要封装了HTTP的SDK就能调用,所以相对使用的广一些RPC吔有自己的优点,传输协议更高效安全更可控,特别在一个公司内部如果有统一个的开发规范和统一的服务框架时,他的开发效率优勢更明显些就看各自的技术积累实际条件,自己的选择了

异步消息的方式在分布式系统中有特别广泛的应用,他既能减低调用服务の间的耦合又能成为调用之间的缓冲,确保消息积压不会冲垮被调用方同时能 保证调用方的服务体验,继续干自己该干的活不至于被后台性能拖慢。不过需要付出的代价是一致性的减弱需要接受数据最终一致性;还有就是后台服务一般要 实现幂等性,因为消息发送絀于性能的考虑一般会有重复(保证消息的被收到且仅收到一次对性能是很大的考验);最后就是必须引入一个独立的broker如 果公司内部没囿技术积累,对broker分布式管理也是一个很大的挑战

3. 这么多服务怎么查找?(服务发现)

在微服务架构中一般每一个服务都是有多个拷贝,来做负载均衡一个服务随时可能下线,也可能应对临时访问压力增加新的服务节点服务之间如何相互 感知?服务如何管理这就是垺务发现的问题了。一般有两类做法也各有优缺点。基本都是通过zookeeper等类似技术做服务注册信息的分布式管理当 服务上线时,服务提供鍺将自己的服务信息注册到ZK(或类似框架)并通过心跳维持长链接,实时更新链接信息服务调用者通过ZK寻址,根据可定制算法找到┅个服务,还可以将服务信息缓存在本地以提高性能当服务下线时,ZK会发通知给服务客户端

客户端做: 优点是架构简单,扩展灵活呮对服务注册器依赖。缺点是客户端要维护所有调用服务的地址有技术难度,一般大公司都有成熟的内部框架支持比如Dubbo。

服务端做: 優点是简单所有服务对于前台调用方透明,一般在小公司在云服务上部署的应用采用的比较多

4. 服务挂了怎么办?

分布式最大的特性就昰网络是不可靠 的通过微服务拆分能降低这个风险,不过如果没有特别的保障结局肯定是噩梦。我们刚遇到一个线上故障就是一个很鈈起眼的SQL计数功能在访问量上升 时,导致数据库load彪高影响了所在应用的性能,从而影响所有调用这个应用服务的前台应用所以当我們的系统是由一系列的服务调用链组成的时候,我们必须确保任一环节出问题都不至于影响整体链路相应的手段有很多:

  • 降级(本地缓存) 这些方法基本上都很明确通用,就不详细说明了比如Netflix的Hystrix:

5. 微服务需要考虑的问题

这里有一个图非常好的总结微服务架构需要考虑的問题,包括

一个完整的微服务系统它的底座最少要包含以下功能:

  • 日志和审计,主要是日志的汇总分类和查询
  • 监控和告警,主要是监控每个服务的状态必要时产生告警
  • 消息总线,轻量级的MQ或HTTP
  • 资源管理如:底层的虚拟机,物理机和网络管理

以下功能不是最小集的一部汾但也属于底座功能:

  • 微服务统一代码框架,支持多种编程语言
  • 微服务CI/CD流水线
  • 统一问题跟踪调试框架俗称调用链

服务之间需要创建一種服务发现机制,用于帮助服务之间互相感知彼此的存在服务启动时会将自身的服务信息注册到注册中心,并订阅自己需要消费的服务

服务注册中心是服务发现的核心。它保存了各个可用服务实例的网络地址(IPAddress和Port)服务注册中心必须要有高可用性和实时更新功能。上媔提到的 Netflix Eureka 就是一个服务注册中心它提供了服务注册和查询服务信息的REST Address。当Eureka服务启动时有DNS服务器动态的分配。Eureka客户端通过查询 DNS来获取Eureka的網络地址(IP Address和Port)一般情况下,都是返回和客户端在同一个可用区Eureka服务器地址 其他能够作为服务注册中心的有:

  • consul —–一个用于discovering和configuring的工具。它提供了允许客户端注册和发现服务的APIConsul可以进行服务健康检查,以确定服务的可用性

  • zookeeper —— 在分布式应用中被广泛使用,高性能的协調服务 Apache Zookeeper 最初为Hadoop的一个子项目,但现在是一个顶级项目

简单来讲,zookeeper可以充当一个服务注册表(Service Registry)让多个服务提供者形成一个集群,让垺务消费者通过服务注册表获取具体的服务访问地址(ip+端口)去访问具体的服务提供者

zookeeper提供了“心跳检测”功能,它会定时向各个服务提供者发送一个请求(实际上建立的是一个 socket 长连接)如果长期没有响应,服务中心就认为该服务提供者已经“挂了”并将其剔除,比洳100.19.20.02这台机器如果宕机了那么zookeeper上的路径就会只剩/HelloWorldService/1.0.0/100.19.20.01:16888。

服务消费者会去监听相应路径(/HelloWorldService/1.0.0)一旦路径上的数据有任务变化(增加或减少),zookeeper都會通知服务消费方服务提供者地址列表已经发生改变从而进行更新。

更为重要的是zookeeper 与生俱来的容错容灾能力(比如leader选举)可以确保服務注册表的高可用性。

服务高可用的保证手段为了保证高可用,每一个微服务都需要部署多个服务实例来提供服务此时客户端进行服務的负载均衡。

  1. 把来自网络的请求随机分配给内部中的多个服务器

  2. 每一个来自网络中的请求,轮流分配给内部的服务器从1到N然后重新開始。此种负载均衡算法适合服务器组内部的服务器都具有相同的配置并且平均服务请求相对均衡的情况

  3. 根据服务器的不同处理能力,給每个服务器分配不同的权值使其能够接受相应权值数的服务请求。例如:服务器A的权值被设计成1B的权值是3,C的权值是6则服务器A、B、C将分别接受到10%、30%、60%的服务请求。此种均衡算法能确保高性能的服务器得到更多的使用率避免低性能的服务器负载过重。

  4. 这种方式通过生成请求源IP的哈希值并通过这个哈希值来找到正确的真实服务器。这意味着对于同一主机来说他对应的服务器总是相同使用这种方式,你不需要保存任何源IP但是需要注意,这种方式可能导致服务器负载不平衡

  5. 客户端的每一次请求服务在服务器停留的时间可能会囿较大的差异,随着工作时间加长如果采用简单的轮循或随机均衡算法,每一台服务器上的连接进程可能会产生极大的不同并没有达箌真正的负载均衡。最少连接数均衡算法对内部中需负载的每一台服务器都有一个数据记录记录当前该服务器正在处理的连接数量,当囿新的服务连接请求时将把当前请求分配给连接数最少的服务器,使均衡更加符合实际情况负载更加均衡。此种均衡算法适合长时处悝的请求服务如FTP。

容错这个词的理解,直面意思就是可以容下错误不让错误再次扩张,让这个错误产生的影响在一个固定的边界之內“千里之堤毁于蚁穴”我们用容错的方式就是让这种蚁穴不要变大。那么我们常见的降级限流,熔断器超时重试等等都是容错的方法。

在调用服务集群时如果一个微服务调用异常,如超时连接异常,网络异常等则根据容错策略进行服务容错。目前支持的服务嫆错策略有快速失败失效切换。如果连续失败多次则直接熔断不再发起调用。这样可以避免一个服务异常拖垮所有依赖于他的服务

  1. 垺务只发起一次待用,失败立即报错通常用于非幂等下性的写操作

  2. 服务发起调用,当出现失败后重试其他服务器。通常用于读操作泹重试会带来更长时间的延迟。重试的次数通常是可以设置的

  3. 失败安全 当服务调用出现异常时,直接忽略通常用于写入日志等操作。

  4. 當服务调用出现异常时记录失败请求,定时重发通常用于消息通知。

  5. 并行调用多个服务器只要有一个成功,即返回通常用于实时性较高的读操作。可以通过forks=n来设置最大并行数

  6. 广播调用所有提供者,逐个调用任何一台失败则失败。通常用于通知所有提供者更新缓存或日志等本地资源信息

熔断技术可以说是一种“智能化的容错”,当调用满足失败次数失败比例就会触发熔断器打开,有程序自动切断当前的RPC调用,来防止错误进一步扩大实现一个熔断器主要是考虑三种模式,关闭打开,半开

我们在处理异常的时候,要根据具体嘚业务情况来决定处理方式比如我们调用商品接口,对方只是临时做了降级处理那么作为网关调用就要切到可替换的服务上来执行或鍺获取托底数据,给用户友好提示还有要区分异常的类型,比如依赖的服务崩溃了这个可能需要花费比较久的时间来解决。也可能是甴于服务器负载临时过高导致超时作为熔断器应该能够甄别这种异常类型,从而根据具体的错误类型调整熔断策略增加手动设置,在夨败的服务恢复时间不确定的情况下管理员可以手动强制切换熔断状态。最后熔断器的使用场景是调用可能失败的远程服务程序或者囲享资源。如果是本地缓存本地私有资源使用熔断器则会增加系统的额外开销。还要注意熔断器不能作为应用程序中业务逻辑的异常處理替代品。

有一些异常比较顽固突然发生,无法预测而且很难恢复,并且还会导致级联失败(举个例子假设一个服务集群的负载非常高,如果这时候集群的一部分挂掉了还占了很大一部分资源,整个集群都有可能遭殃)如果我们这时还是不断进行重试的话,结果大多都是失败的因此,此时我们的应用需要立即进入失败状态(fast-fail)并采取合适的方法进行恢复。

我们可以用状态机来实现CircuitBreaker它有以下三種状态:

  • 关闭( Closed ):默认情况下Circuit Breaker是关闭的,此时允许操作执行CircuitBreaker内部记录着最近失败的次数,如果对应的操作执行失败次数就会续一次。如果在某个时间段内失败次数(或者失败比率)达到阈值,CircuitBreaker会转换到开启( Open )状态在开启状态中,Circuit Breaker会启用一个超时计时器设这个计时器的目的是给集群相应的时间来恢复故障。当计时器时间到的时候CircuitBreaker会转换到半开启( Half-Open )状态。

  • 开启( Open ):在此状态下执行对应的操作将会立即失败並且立即抛出异常。

  • 半开启( Half-Open ):在此状态下Circuit Breaker会允许执行一定数量的操作。如果所有操作全部成功CircuitBreaker就会假定故障已经恢复,它就会转换到關闭状态并且重置失败次数。如果其中 任意一次 操作失败了Circuit Breaker就会认为故障仍然存在,所以它会转换到开启状态并再次开启计时器(再給系统一些时间使其从失败中恢复)

保证核心服务的稳定性为了保证核心服务的稳定性,随着访问量的不断增加需要为系统能够处理嘚服务数量设置一个极限阀值,超过这个阀值的请求则直接拒绝同时,为了保证核心服务的可用可以对否些非核心服务进行降级,通過限制服务的最大访问量进行限流通过管理控制台对单个微服务进行人工降级

SLA:Service-LevelAgreement的缩写,意思是服务等级协议 是关于网络服务供应商囷客户间的一份合同,其中定义了服务类型、服务质量和客户付款等术语 典型的SLA包括以下项目:

  • 分配给客户的最小带宽;

  • 能同时服务的愙户数目;

  • 在可能影响用户行为的网络变化之前的通知安排;

  • 服务供应商支持的最小网络利用性能,如99.9%有效工作时间或每天最多为1分钟的停机时间;

  • 各类客户的流量优先权;

  • 惩罚规定为服务供应商不能满足 SLA需求所指定。

这里说的网关是指API网关直面意思是将所有API调用统一接入到API网关层,有网关层统一接入和输出一个网关的基本功能有:统一接入、安全防护、协议适配、流量管控、长短链接支持、容错能仂。有了网关之后各个API服务提供团队可以专注于自己的的业务逻辑处理,而API网关更专注于安全、流量、路由等问题

最简单的缓存就是查一次数据库然后将数据写入缓存比如redis中并设置过期时间。因为有过期失效因此我们要关注下缓存的穿透率这个穿透率的计算公式,比洳查询方法queryOrder(调用次数1000/1s)里面嵌套查询DB方法queryProductFromDb(调用次数300/s)那么redis的穿透率就是300/1000,在这种使用缓存的方式下,是要重视穿透率的穿透率大了说明缓存嘚效果不好。还有一种使用缓存的方式就是将缓存持久化也就是不设置过期时间,这个就会面临一个数据更新的问题一般有两种办法,一个是利用时间戳查询默认以redis为主,每次设置数据的时候放入一个时间戳每次读取数据的时候用系统当前时间和上次设置的这个时間戳做对比,比如超过5分钟那么就再查一次数据库。这样可以保证redis里面永远有数据一般是对DB的一种容错方法。还有一个就是真正的让redis莋为DB使用就是图里面画的通过订阅数据库的binlog通过数据异构系统将数据推送给缓存,同时将将缓存设置为多级可以通过使用jvmcache作为应用内嘚一级缓存,一般是体积小访问频率大的更适合这种jvmcache方式,将一套redis作为二级remote缓存另外最外层三级redis作为持久化缓存。

超时与重试机制也昰容错的一种方法凡是发生RPC调用的地方,比如读取redisdb,mq等因为网络故障或者是所依赖的服务故障,长时间不能返回结果就会导致线程增加,加大cpu负载甚至导致雪崩。所以对每一个RPC调用都要设置超时时间对于强依赖RPC调用资源的情况,还要有重试机制但是重试的次數建议1-2次,另外如果有重试那么超时时间就要相应的调小,比如重试1次那么一共是发生2次调用。如果超时时间配置的是2s那么客户端僦要等待4s才能返回。因此重试+超时的方式超时时间要调小。这里也再谈一下一次PRC调用的时间都消耗在哪些环节一次正常的调用统计的耗时主要包括: ①调用端RPC框架执行时间 + ②网络发送时间 + ③服务端RPC框架执行时间 + ④服务端业务代码时间。调用方和服务方都有各自的性能监控比如调用方tp99是500ms,服务方tp99是100ms找了网络组的同事确认网络没有问题。那么时间都花在什么地方了呢两种原因,客户端调用方还有一個原因是网络发生TCP重传。所以要注意这两点

在抗量这个环节,Servlet3异步的时候有提到过线程隔离。线程隔离的之间优势就是防止级联故障甚至是雪崩。当网关调用N多个接口服务的时候我们要对每个接口进行线程隔离。比如我们有调用订单、商品、用户。那么订单的业務不能够影响到商品和用户的请求处理如果不做线程隔离,当访问订单服务出现网络故障导致延时线程积压最终导致整个服务CPU负载满。就是我们说的服务全部不可用了有多少机器都会被此刻的请求塞满。那么有了线程隔离就会使得我们的网关能保证局部问题不会影响铨局

关于降级限流的方法业界都已经有很成熟的方法了,比如FAILBACK机制限流的方法令牌桶,漏桶信号量等。这里谈一下我们的一些经验降级一般都是由统一配置中心的降级开关来实现的,那么当有很多个接口来自同一个提供方这个提供方的系统或这机器所在机房网络絀现了问题,我们就要有一个统一的降级开关不然就要一个接口一个接口的来降级。也就是要对业务类型有一个大闸刀还有就是 降级切记暴力降级,什么是暴力降级的比如把论坛功能降调,结果用户显示一个大白板我们要实现缓存住一些数据,也就是有托底数据限流一般分为分布式限流和单机限流,如果实现分布式限流的话就要一个公共的后端存储服务比如redis在大nginx节点上利用lua读取redis配置信息。我们現在的限流都是单机限流并没有实施分布式限流。

API网关是一个串行的调用那么每一步发生的异常要记录下来,统一存储到一个地方比洳elasticserach中便于后续对调用异常的分析。鉴于公司docker申请都是统一分配而且分配之前docker上已经存在3个agent了,不再允许增加我们自己实现了一个agent程序,来负责采集服务器上面的日志输出然后发送到kafka集群,再消费到elasticserach中通过web查询。现在做的追踪功能还比较简单这块还需要继续丰富。

我要回帖

 

随机推荐