比如每日有大量用户访问和数据替换-服务器的带宽需求与网站的访问量密切相关-那么就须要更大的带宽来满足需求-访问量-假设你的网站流量大 (比如每日有大事的句子)
SpringBeanDefinition元信息定义形式
BeanDefinition是一个蕴含Bean元数据的对象。它形容了如何创立Bean实例、Bean属性的值以及Bean之间的依赖相关。可以经常使用多种形式来定义BeanDefinition元信息,包括:
除此之外,还可以经过成功BeanDefinitionRegistryPostProcessor接口来自定义BeanDefinition的生成环节。这个接口有一个方法postProcessBeanDefinitionRegistry(),准许开发人员灵活地参与、修正或删除BeanDefinition元信息。
XML性能文件定义Bean的元数据
注解定义Bean的元数据
@Service(value="HelloService")publicclassHelloService{privatefinalLoggerlogger=LoggerFactory.getLogger(HelloService.class);privatefinalHelloAsyncServicehelloAsyncService;publicHelloService(HelloAsyncServicehelloAsyncService){this.helloAsyncService=helloAsyncService;}}
Java性能类定义Bean的元数据
@Component(value="balanceProcessor")publicclassBalanceRedisProcessorServiceimplementsEntryHandler<Balance>,Runnable{@Autowired(required=true)publicBalanceRedisProcessorService(RedisUtilsredisUtils,CanalConfigcanalConfig,@Qualifier("ownThreadPoolExecutor")Executorexecutor,RocketMQProducerrocketMqProducer){this.redisUtils=redisUtils;this.canalConfig=canalConfig;this.executor=executor;this.rocketMQProducer=rocketMqProducer;}}
BeanDefinition的元数据解析
在Spring中,无论是经过XML、注解、Java性能类定义Bean元数据,最终都是须要转换成 BeanDefinition 对象,而后被注册到Spring容器中。
而BeanDefinition的创立环节,确实是经过AbstractBeanDefinition及其派生类、``等一系列工具类成功的。
源码剖析XML是如何转化为SpringBeanDefinition的
将xml文件中的性能转为为BeanDefinition须要依赖自XmlBeanDefinitionReader类中的loadBeanDefinitions方法。
选自:SpringFramework5.2.20RELEASE版本的XmlBeanDefinitionReader。
privatefinalThreadLocal<Set<EncodedResource>>resourcesCurrentlyBeingLoaded=newNamedThreadLocal<Set<EncodedResource>>("XMLbeandefinitionresourcescurrentlybeingloaded"){@OverrideprotectedSet<EncodedResource>initialValue(){returnnewHashSet<>(4);}};/***LoadbeandefinitionsfromthespecifiedXMLfile.*@paramencodedResourcetheresourcedescriptorfortheXMLfile,*allowingtospecifyanencodingtouseforparsingthefile*@returnthenumberofbeandefinitionsfound*@throwsBeanDefinitionStoreExceptionincaseofloadingorparsingerrors*/publicintloadBeanDefinitions(EncodedResourceencodedResource)throwsBeanDefinitionStoreException{Assert.notNull(encodedResource,"EncodedResourcemustnotbenull");if(logger.isTraceEnabled()){logger.trace("LoadingXMLbeandefinitionsfrom"+encodedResource);}Set<EncodedResource>currentResources=this.resourcesCurrentlyBeingLoaded.get();if(!currentResources.add(encodedResource)){thrownewBeanDefinitionStoreException("Detectedcyclicloadingof"+encodedResource+"-checkyourimportdefinitions!");}try(InputStreaminputStream=encodedResource.getResource().getInputStream()){InputSourceinputSource=newInputSource(inputStream);if(encodedResource.getEncoding()!=null){inputSource.setEncoding(encodedResource.getEncoding());}//实践上从指定的XML文件加载Bean定义returndoLoadBeanDefinitions(inputSource,encodedResource.getResource());}catch(IOExceptionex){thrownewBeanDefinitionStoreException("IOExceptionparsingXMLdocumentfrom"+encodedResource.getResource(),ex);}finally{currentResources.remove(encodedResource);if(currentResources.isEmpty()){this.resourcesCurrentlyBeingLoaded.remove();}}}//实践上从指定的XML文件加载Bean定义/***ActuallyloadbeandefinitionsfromthespecifiedXMLfile.*@paraminputSourcetheSAXInputSourcetoreadfrom*@paramresourcetheresourcedescriptorfortheXMLfile*@returnthenumberofbeandefinitionsfound*@throwsBeanDefinitionStoreExceptionincaseofloadingorparsingerrors*@see#doLoadDocument*@see#registerBeanDefinitions*/protectedintdoLoadBeanDefinitions(InputSourceinputSource,Resourceresource)throwsBeanDefinitionStoreException{try{Documentdoc=doLoadDocument(inputSource,resource);intcount=registerBeanDefinitions(doc,resource);if(logger.isDebugEnabled()){logger.debug("Loaded"+count+"beandefinitionsfrom"+resource);}returncount;}}
源码剖析性能类、注解是如何转化为SpringBeanDefinition的
在Spring中,性能类和注解都可以被转换为Bean定义(BeanDefinition)。上方是关于如何将性能类和注解转换为Bean定义的简明源码剖析:
总而言之,无论是性能类还是注解,Spring都会经过解析注解并生成对应的Bean定义,最终将这些Bean定义注册到DefaultListableBeanFactory中。这样,在容器启动时,Spring就能够依据这些Bean定义来实例化Bean并启动依赖注入。
性能类、注解转换为SpringBeanDefition源码后续博客中展现,敬请等候。
如何手动结构BeanDefinition
Bean定义
publicclassUser{privateLongid;privateStringname;publicLonggetId(){returnid;}publicvoidsetId(Longid){this.id=id;}publicStringgetName(){returnname;}publicvoidsetName(Stringname){this.name=name;}@OverridepublicStringtoString(){return"User{"+"id="+id+",+name+'''+'}';}}
经过BeanDefinitionBuilder构建
//经过BeanDefinitionBuilder构建BeanDefinitionBuilderbeanDefinitionBuilder=BeanDefinitionBuilder.genericBeanDefinition(User.class);//经过属性设置beanDefinitionBuilder.addPropertyValue("id",1L).addPropertyValue("name","群众号:种棵代码技术树");//失掉BeanDefinition实例BeanDefinitionbeanDefinition=beanDefinitionBuilder.getBeanDefinition();//BeanDefinition并非Bean终态,可以自定义修正System.out.println(beanDefinition);
经过AbstractBeanDefinition以及派生类
//2.经过AbstractBeanDefinition以及派生类GenericBeanDefinitiongenericBeanDefinition=newGenericBeanDefinition();//设置Bean类型genericBeanDefinition.setBeanClass(User.class);//经过MutablePropertyValues批量操作属性MutablePropertyValuespropertyValues=newMutablePropertyValues();propertyValues.add("id",1L).add("name","群众号:种棵代码技术树");//经过setMutablePropertyValues批量操作属性genericBeanDefinition.setPropertyValues(propertyValues);
谁能详细说明一下 网站服务器带宽 和 网站 访问量之间的关系
网站服务器的带宽是指你的服务器接入到运营商的接口带宽,就好比是一条进入你网站的路,带宽越大,能走的车就越多,网站的能访问的人就越多,如果带宽小了的话,别人打开这个网站会很慢,比较卡。 访问量就是某段时间内有多少人进入了这个网站。 一天有三万IP,说明每小时也就一千多人进入这个网站,每分种十到二十个人打开这个网页,这对带宽的需要求量不是很大。
网站架构的硬架构
通常老板花钱请我们架构网站的时候,会给我们提出一些目标,诸如网站每天要能承受100万PV的访问量等等。 这时我们要预算一下大概需要多大的带宽,计算带宽大小主要涉及两个指标(峰值流量和页面大小),我们不妨在计算前先做出必要的假设:第一:假设峰值流量是平均流量的5倍。 第二:假设每次访问平均的页面大小是100K字节左右。 如果100万PV的访问量在一天内平均分布的话,折合到每秒大约12次访问,如果按平均每次访问页面的大小是100K字节左右计算的话,这12次访问总计大约就是1200K字节,字节的单位是Byte,而带宽的单位是bit,它们之间的关系是1Byte = 8bit,所以1200K Byte大致就相当于9600K bit,也就是9Mbps的样子,实际情况中,我们的网站必须能在峰值流量时保持正常访问,所以按照假设的峰值流量算,真实带宽的需求应该在45Mbps 左右。 当然,这个结论是建立在前面提到的两点假设的基础上,如果你的实际情况和这两点假设有出入,那么结果也会有差别。 先看我们都需要哪些服务器:图片服务器,页面服务器,数据库服务器,应用服务器,日志服务器等等。 对于访问量大点的网站而言,分离单独的图片服务器和页面服务器相当必要,我们可以用lighttpd来跑图片服务器,用apache来跑页面服务器,当然也可以选择别的,甚至,我们可以扩展成很多台图片服务器和很多台页面服务器,并设置相关域名,如和 ,页面里的图片路径都使用绝对路径,如<img src=/>,然后设置DNS轮循,达到最初级的负载均衡。 当然,服务器多了就不可避免的涉及一个同步的问题,这个可以使用rsync软件来搞定。 数据库服务器是重中之重,因为网站的瓶颈问题十有八九是出在数据库身上。 现在一般的中小网站多使用MySQL数据库,不过它的集群功能似乎还没有达到stable的阶段,所以这里不做评价。 一般而言,使用MySQL数据库的时候,我们应该搞一个主从(一主多从)结构,主数据库服务器使用innodb表结构,从数据服务器使用myisam表结构,充分发挥它们各自的优势,而且这样的主从结构分离了读写操作,降低了读操作的压力,甚至我们还可以设定一个专门的从服务器做备份服务器,方便备份。 不然如果你只有一台主服务器,在大数据量的情况下,mysqldump基本就没戏了,直接拷贝数据文件的话,还得先停止数据库服务再拷贝,否则备份文件会出错。 但对于很多网站而言,即使数据库服务仅停止了一秒也是不可接受的。 如果你有了一台从数据库服务器,在备份数据的时候,可以先停止服务(slave stop)再备份,再启动服务(slave start)后从服务器会自动从主服务器同步数据,一切都没有影响。 但是主从结构也是有致命缺点的,那就是主从结构只是降低了读操作的压力,却不能降低写操作的压力。 为了适应更大的规模,可能只剩下最后这招了:横向/纵向分割数据库。 所谓横向分割数据库,就是把不同的表保存到不同的数据库服务器上,比如说 用户表保存在A数据库服务器上,文章表保存在B数据库服务器上,当然这样的分割是有代价的,最基本的就是你没法进行LEFT JOIN之类的操作了。 所谓纵向分割数据库,一般是指按照用户标识(user_id)等来划分数据存储的服务器,比如说:我们有5台数据库服务器,那么 “user_id % 5 + 1”等于1的就保存到1号服务器,等于2的就保存到2号服务器,以此类推,纵向分隔的原则有很多种,可以视情况选择。 不过和横向分割数据库一样,纵向分割数据库也是有代价的,最基本的就是我们在进行如COUNT, SUM等汇总操作的时候会麻烦很多。 综上所述,数据库服务器的解决方案一般视情况往往是一个混合的方案,以其发挥各种方案的优势,有时候还需要借助memcached之类的第三方软件,以便适应更大访问量的要求。 如果有专门的应用服务器来跑PHP脚本是最合适不过的了,那样我们的页面服务器只保存静态页面就可以了,可以给应用服务器设置一些诸如之类的域名来和页面服务器加以区别。 对于应用服务器,我还是更倾向于使用prefork模式的apache,配上必要的xcache之类的PHP缓存软件,加载模块要越少越好,除了mod_rewrite等必要的模块,不必要的东西统统舍弃,尽量减少httpd进程的内存消耗,而那些图片服务器,页面服务器等静态内容就可以使用lighttpd或者tux来搞,充分发挥各种服务器的特点。 如果条件允许,独立的日志服务器也是必要的,一般小网站的做法都是把页面服务器和日志服务器合二为一了,在凌晨访问量不大的时候cron运行前一天的日志计算,不过如果你使用awstats之类的日志分析软件,对于百万级访问量而言,即使按天归档,也会消耗很多时间和服务器资源去计算,所以分离单独的日志服务器还是有好处的,这样不会影响正式服务器的工作状态。
免责声明:本文转载或采集自网络,版权归原作者所有。本网站刊发此文旨在传递更多信息,并不代表本网赞同其观点和对其真实性负责。如涉及版权、内容等问题,请联系本网,我们将在第一时间删除。同时,本网站不对所刊发内容的准确性、真实性、完整性、及时性、原创性等进行保证,请读者仅作参考,并请自行核实相关内容。对于因使用或依赖本文内容所产生的任何直接或间接损失,本网站不承担任何责任。