
可以使用Spring 的事务管理器, 在你要控制事务的方法上加上@Transaction注解即可, 不用自己控制事务的开始,提交和回滚。
完全避免超时是不可能的, 任何服务也都不能保证100%的可用, 所以我觉得要业务上做好异常处理控制, 针对不同的业务场景选择丢弃还是重试。
补充一点, 高并发场景上要考虑是使用内存还是缓存, 建议是使用缓存memcache或者redis都行, 防止并发量过高导致内存爆掉。
nginx转发到哪儿? 是不是下游处理具体业务逻辑的地方报的404, 正常情况下nginx作为负载均衡器,支持上万的并发是没问题的。
首先主从延迟1-2s,这个可优化的, 也有成熟的方案, 延迟实际应该是毫秒级别的。
其次我有一个疑问, 不知道你们文章的评论量有多少? 如果高并发情况下, 评论量势必会很大, 是否进行了分库分表操作, 目前我的理解你们评论表应该有要对文章id和用户名分别建索引, 这种情形下进行分库分表就比较麻烦了。 当然这个疑问和楼主说的问题就不相关了。 针对评论这种场景, 可以考虑使用mysql + ElasticSearch 的方式存放, mysql表只对点评ID建唯一索引, 所有的查询都走ES(ES存放什么根据业务需要, 比如楼主这种业务, 可以存放文章Id, 用户名, 点评ID), 反查出点评ID然后从mysql中查询对应的点评内容。 使用这种架构mysql可按照点评ID分库分表, ElasticSearch自身支持水平扩容。
Spring 的bean的scope设置成prototype, 就是每次都要创建一个实例, 可以看一下Spring的源码, 创建一个Spring实例是很复杂的一个过程, CGlib代理只是其中的一步,底层也是通过反射完成的, 我觉得耗时的关键不在 CGlib代理, 而是在整个Spring加载和实例化bean的过程。 通常情况下使用Spring来管理bean都是将scope设置成singleton, 这样bean实例就是一个单例, 不用每次getBean时都实例化一遍。 具体能不能用singleton要看你的实际应用场景了。
基于楼主的问题, 实现高并发, 可以从两个角度来考虑。
第一个角度是优化接口逻辑, 降低接口响应时间。 可以借助一些工具分析每一步的耗时, 这样就知道哪块可以优化。 通常的做法是使用缓存来挡流量。
第二个角度就是扩容机器, 具体扩容多少机器可参考单台机器最大支持的并发量。
接口优化了,机器也扩容了, 后面需要做的就是按照既定的目标对系统进行压测, 压测不光是看自身系统能不能支持这么高的qps, 还要看底层的db, 下游的接口是否能支持。如果db不支持, 可考虑进行主从分离, 分库分表; 如果下游接口不支持需要给下游接口沟通让其扩容。
基于楼主的问题, 实现高并发, 可以从两个角度来考虑。
第一个角度是优化接口逻辑, 降低接口响应时间。 可以借助一些工具分析每一步的耗时, 这样就知道哪块可以优化。 通常的做法是使用缓存来挡流量。
第二个角度就是增加机器, 具体增加多少机器可参考单台机器最大支持的并发量。
接口优化了,机器也添加了, 后面需要做的就是按照既定的目标对系统进行压测, 压测不光是看自身系统能不能支持这么高的qps, 还要看底层的db, 下游的接口是否能支持。如果db不支持, 可考虑进行主从分离, 分库分表; 如果下游接口不支持需要给下游接口沟通让其扩容。
这个问题首先涉及到工程中代码结构的问题,正常来说会分成以下四层, 从低向上依次是:
dao层: 存放的是对底层数据库的操作
service层: 对底层的封装, 比如对dao层的封装, 对外围接口的封装等
biz层: 即业务层, 该层存放的是业务逻辑类
controller层: 及入口层, 该层负责对请求参数进行校验, 调用biz层处理业务逻辑, 然后对结果进行组装。
弄清楚了代码结构后再说一下异常处理原则: 能处理就早处理
基于楼主的例子, db异常应该是在service层被spring aop事务管理器捕获了, 即就是说@Transactional应该放在service层的方法上。另外, 一旦回滚事务管理器还会抛出数据库回滚异常, 接着biz层就要捕获这个异常来判定db操作是否成功,进而执行不同的逻辑处理。
先说一下AOP是干什么呢, AOP是面向切面的编程, 通过AOP可以将业务的各个部分进行隔离,从而是各个部分耦合度降低。常用于做日志记录,性能统计,安全控制,事务处理,异常处理等。
接着再介绍几个概念:
Joint point:表示在程序中明确定义的点,典型的包括方法调用,对类成员的访问以及异常处理程序块的执行等等,它自身还可以嵌套其它 joint point。
Pointcut:表示一组 joint point,这些 joint point 或是通过逻辑关系组合起来,或是通过通配、正则表达式等方式集中起来,它定义了相应的 Advice 将要发生的地方。
Advice:Advice 定义了在 pointcut 里面定义的程序点具体要做的操作,它通过 before、after 和 around 来区别是在每个 joint point 之前、之后还是代替执行的代码
Advisor: 通知器, 包括通知和切点
结合上面的概念再来看楼主的例子就比较清晰了
定义了切点, 即要拦截哪些操作。 这个例子就是说要拦截com.ace.service.impl这个包下的所有以Impl结尾的所有public方法。
定义了通知器, 该通知器指定了刚刚说的那个切点, 还指定了基于这个切点要做什么操作, 具体的操作逻辑在txAdvice中。
Tomcat的连接数和jvm参数要根据机器的硬件指标以及要部署的应用的的情况调整的, 不存在一种普世的方式。 针对一般的应用可按照一楼给出的配置, 如果对性能要求很高的应用, 需要通过分析测试来调整对应的参数,以让机器能达到高利用率。
首先说一下什么是垃圾? 一般来说,所有指向对象的引用都已失效,不可能再有程序能调用到这个对象,那么这个对象就成了垃圾,应该被回收。 而Java通常是基于GC Roots的可达性来判断对象的引用是否失效的。 因此, 基于你这个问题, 弄清楚了GC Roots可达行即可解决。
GC Roots有一些几类:
上面楼主例子中的cache属于第一类:虚拟机栈中的引用对象, 所有它不是垃圾, 即使发生GC 也不会被回收
而方法中的i是一个局部变量, 方执行结束后就处于GC Roots不可达的状态,它被当做的垃圾, 但是否要被回收还要看是否发生了GC。
设置多大要看应用的具体情况而定, 你出现的PermGen Space OutOfMemory说明了是永久代内存溢出了, 这一部分用于存放Class和Meta的信息,Class在被 Load的时候被放入, 可能是你的应用会加载了很多CLASS导致的, 稳定确定了要解决的话只需要调整永久代区域的大小, 方法如你上面所说将PermSize和MaxPermSize调大些。
Spring + Dubbo 是很经典的微服务架构。 Dubbo作为一个分布式RPC架构来解决微服务之间的方法调用问题;Spring作为一个容器来管理服务中Bean的生命周期,其中Dubbo的服务提供者和消费者也可作为bean交由Spring统一管理。
这个要看你使用的是消息队列是否支持了!
比如kafka是可以支持从头开始消费的, 需要在对应的spring-kafka消费者客户端配置以下参数:
目前市面上有些分布式事务的产品, 比如阿里的GTS, 但是否要使用分布式事务要根据系统所处的场景判断。 如果要求强一致性并且并发量不高的情况下可以考虑使用这些分布式产品。 如果你的系统所处的是一个高并发的场景(比如TPS达到了几十万), 这个时候市面上的分布式事务产品很难满足需求的(很多分布式事务的产品强依赖业务底层的数据库, 高并发时底层数据库很容易成为瓶颈), 这个时候就不得不考虑使用消息队列+补偿机制来解决了。
可以把订单提交操作进行划分成主流程和附属流程, 主流程同步, 附属流程异步。 比如主流程是校验参数,扣减库存, 然后将订单信息落库, 附属流程是:给用户添加积分,主流程执行完毕后就认为订单创建成功,并把结果返回给前端。 而附属流程可通过在订单创建成功后发送mq通知积分系统给用户添加积分, 保证最终一致性即可。
如果打开的网页是自己的网页,可以通过Request中的User-Agent来判断是来自哪个客户端或者浏览器。
如果不是你也可以在外面包一层, 扫码先到你自己的服务上,然后在进行302跳转。 这样你就可以通过Request中的User-Agent来判断是来自哪个客户端或者浏览器
google zxing包, 提供了二维码的生成和解析方法。
楼主意思是对扫码支付的用户进行分析吗? 比如分析用户地理位置分布, 年龄分布, 使用支付工具等等